1- import { canonicalFileName , ensureExtension , type SyncTracker , sanitizeFilePath } from "@code-link/shared"
1+ import { canonicalFileName , ensureExtension , type SyncTracker } from "@code-link/shared"
22import { framer } from "framer-plugin"
33import * as log from "./utils/logger"
44
5- // TODO:
6- // - what is CLI file name vs canonical file name
7- // - check if the handles can become stale
8- // - inconsistent error handling of Framer API calls
9- // - other inline comments below
10-
115/**
126 * Plugin API Handlers
137 *
@@ -16,41 +10,31 @@ import * as log from "./utils/logger"
1610
1711export class CodeFilesAPI {
1812 private lastSnapshot = new Map < string , string > ( )
19- // private codeFiles = new Map<string, CodeFile>()
20-
21- // @TODO figure out if good idea
22- // private async getPossiblyStableCodeFileHandle(name: string) {
23- // const file = this.codeFiles.get(name)
24- // if (file) return file
25-
26- // const allCodeFiles = await framer.getCodeFiles()
27-
28- // this.codeFiles = new Map<string, CodeFile>()
2913
30- // return
31- // }
32-
33- private async getAllCodeFiles ( ) {
14+ private async getCodeFilesWithCanonicalNames ( ) {
15+ // Always all files instead of single file calls.
16+ // The API internally does that anyways.
17+ // Also ensures everything is fresh.
3418 const codeFiles = await framer . getCodeFiles ( )
3519
3620 return codeFiles . map ( file => {
3721 const source = file . path || file . name
3822 return {
39- name : toCliFileName ( source ) ,
23+ name : canonicalFileName ( source ) ,
4024 content : file . content ,
4125 }
4226 } )
4327 }
4428
4529 async publishSnapshot ( socket : WebSocket ) {
46- const files = await this . getAllCodeFiles ( )
30+ const files = await this . getCodeFilesWithCanonicalNames ( )
4731 socket . send ( JSON . stringify ( { type : "file-list" , files } ) )
4832 this . lastSnapshot . clear ( )
4933 files . forEach ( file => this . lastSnapshot . set ( file . name , file . content ) )
5034 }
5135
5236 async handleFramerFilesChanged ( socket : WebSocket , tracker : SyncTracker ) {
53- const files = await this . getAllCodeFiles ( )
37+ const files = await this . getCodeFilesWithCanonicalNames ( )
5438 const seen = new Set < string > ( )
5539
5640 for ( const file of files ) {
@@ -72,7 +56,6 @@ export class CodeFilesAPI {
7256 }
7357 }
7458
75- // @TODO : Looping again could be more expensive than diffing.
7659 for ( const fileName of Array . from ( this . lastSnapshot . keys ( ) ) ) {
7760 if ( ! seen . has ( fileName ) ) {
7861 socket . send (
@@ -88,9 +71,9 @@ export class CodeFilesAPI {
8871 }
8972
9073 async applyRemoteChange ( fileName : string , content : string , socket : WebSocket ) {
91- const cliName = toCliFileName ( fileName )
74+ const normalizedName = canonicalFileName ( fileName )
9275 // Update snapshot BEFORE upsert to prevent race with file subscription
93- this . lastSnapshot . set ( cliName , content )
76+ this . lastSnapshot . set ( normalizedName , content )
9477
9578 const updatedAt = await upsertFramerFile ( fileName , content )
9679 // Send file-synced message with timestamp
@@ -101,22 +84,21 @@ export class CodeFilesAPI {
10184 socket . send (
10285 JSON . stringify ( {
10386 type : "file-synced" ,
104- fileName : cliName ,
87+ fileName : normalizedName ,
10588 remoteModifiedAt : syncTimestamp ,
10689 } )
10790 )
10891 }
10992
11093 async applyRemoteDelete ( fileName : string ) {
11194 await deleteFramerFile ( fileName )
112- this . lastSnapshot . delete ( toCliFileName ( fileName ) )
95+ this . lastSnapshot . delete ( canonicalFileName ( fileName ) )
11396 }
11497
11598 async readCurrentContent ( fileName : string ) {
116- // @TODO , again, do we need ALL FILES
117- const files = await this . getAllCodeFiles ( )
118- const cliName = toCliFileName ( fileName )
119- return files . find ( file => file . name === cliName ) ?. content
99+ const files = await this . getCodeFilesWithCanonicalNames ( )
100+ const normalizedName = canonicalFileName ( fileName )
101+ return files . find ( file => file . name === normalizedName ) ?. content
120102 }
121103
122104 async fetchConflictVersions ( requests : { fileName : string ; lastSyncedAt ?: number } [ ] ) {
@@ -135,7 +117,6 @@ export class CodeFilesAPI {
135117 }
136118
137119 const versionPromises = requests . map ( async request => {
138- // @TODO we do this a lot?
139120 const file = codeFiles . find (
140121 f => canonicalFileName ( f . path || f . name ) === canonicalFileName ( request . fileName )
141122 )
@@ -175,34 +156,27 @@ export class CodeFilesAPI {
175156 }
176157}
177158
178- // @TODO naming is not clear between all path functions, and when to use which.
179- function toCliFileName ( filePath : string ) {
180- const sanitized = sanitizeFilePath ( filePath , false ) . path
181- return ensureExtension ( sanitized || canonicalFileName ( filePath ) )
182- }
183-
184159async function upsertFramerFile ( fileName : string , content : string ) : Promise < number | undefined > {
185- const normalizedTarget = canonicalFileName ( fileName )
186- // @TODO : investigate if we should keep codeFileHandles around rather than getCodeFiles each time
160+ const normalisedName = canonicalFileName ( fileName )
187161 const codeFiles = await framer . getCodeFiles ( )
188- const existing = codeFiles . find ( file => canonicalFileName ( file . path || file . name ) === normalizedTarget )
162+ const existing = codeFiles . find ( file => canonicalFileName ( file . path || file . name ) === normalisedName )
189163
190164 if ( existing ) {
191165 await existing . setFileContent ( content )
192166 return Date . now ( )
193167 }
194168
195- await framer . createCodeFile ( ensureExtension ( normalizedTarget ) , content , {
169+ await framer . createCodeFile ( ensureExtension ( normalisedName ) , content , {
196170 editViaPlugin : false ,
197171 } )
198172
199173 return Date . now ( )
200174}
201175
202176async function deleteFramerFile ( fileName : string ) {
203- const normalizedTarget = canonicalFileName ( fileName )
177+ const normalisedName = canonicalFileName ( fileName )
204178 const codeFiles = await framer . getCodeFiles ( )
205- const existing = codeFiles . find ( file => canonicalFileName ( file . path || file . name ) === normalizedTarget )
179+ const existing = codeFiles . find ( file => canonicalFileName ( file . path || file . name ) === normalisedName )
206180
207181 if ( existing ) {
208182 await existing . remove ( )
0 commit comments