@@ -4,28 +4,35 @@ import { Api, Causal, Cursor, Doc, Sdk } from "./bindings"
44
55let API : Api ;
66
7- const init = async ( pkg : number [ ] ) => {
7+ const init = async ( appId : string , pkg : number [ ] ) => {
88 if ( API ) {
9- return await API . createPersistent ( "tlfs-0.1.0" , pkg ) ;
9+ return await API . createPersistent ( appId , pkg ) ;
1010 }
1111 else {
12- //const x = await wbindgen("../pkg-wasm-bindgen/local_first_bg.wasm");
12+ // There are two ways to load the wasm module:
13+ // 1) Keep the wasm as a separate ES module and load/fetch it on demand.
14+ // This is a bit more efficient in the browser, but adds burden to library
15+ // users when bundling and shipping their app.
16+ // ```
17+ // const x = await wbindgen("../pkg-wasm-bindgen/local_first_bg.wasm");
18+ // ```
19+ // 2) Inline the wasm. Easy, works everywhere, is only loaded once anyway:
1320 const x = await wbindgen ( wasmbin )
1421
1522 API = new Api ( ) ;
1623 // @ts -ignore
1724 API . initWithInstance ( { exports : x } ) ;
18- return await API . createPersistent ( "tlfs-0.1.0" , pkg ) ;
25+ return await API . createPersistent ( appId , pkg ) ;
1926 }
2027
2128} ;
2229
2330class LocalFirst {
2431 public sdk ! : Sdk ;
2532
26- static async create ( pkg : number [ ] ) {
33+ static async create ( appId : string , pkg : number [ ] ) {
2734 const w = new LocalFirst ( ) ;
28- w . sdk = await init ( pkg ) ;
35+ w . sdk = await init ( appId , pkg ) ;
2936 return w ;
3037 }
3138
@@ -35,12 +42,13 @@ class LocalFirst {
3542}
3643
3744const traverse = ( cursor : Cursor , p : any ) => {
38- if ( cursor . pointsAtArray ( ) ) {
45+ const ty = cursor . typeOf ( )
46+ if ( pointsAtArray ( ty ) ) {
3947 cursor . arrayIndex ( Number ( p ) ) ;
40- } else if ( cursor . pointsAtStruct ( ) ) {
48+ } else if ( pointsAtStruct ( ty ) ) {
4149 const field = p . toString ( )
4250 cursor . structField ( field )
43- } else if ( cursor . pointsAtTable ( ) ) {
51+ } else if ( pointsAtTable ( ty ) ) {
4452 const field = p . toString ( )
4553 cursor . mapKeyStr ( field )
4654 } else {
@@ -50,13 +58,11 @@ const traverse = (cursor: Cursor, p: any) => {
5058
5159const get = < T > ( doc : Doc , cursor_ ?: Cursor ) => ( target : T , p : string | symbol , receiver : any ) => {
5260 const cursor = cursor_ || doc . createCursor ( )
53- console . log ( "get" , target , p , receiver )
5461
5562 traverse ( cursor , p )
56-
57- if ( cursor . pointsAtValue ( ) ) {
58- switch ( cursor . valueType ( ) ) {
59- case "null" : { return undefined ; }
63+ const ty = cursor . typeOf ( )
64+ if ( pointsAtValue ( ty ) ) {
65+ switch ( cursor . typeOf ( ) ) {
6066 case "bool" : { return cursor . flagEnabled ( ) }
6167 case "Reg<bool>" :
6268 { return Array . from ( cursor . regBools ( ) ) [ 0 ] }
@@ -66,6 +72,7 @@ const get = <T>(doc: Doc, cursor_?: Cursor) => (target: T, p: string | symbol, r
6672 { return Array . from ( cursor . regI64s ( ) ) [ 0 ] }
6773 case "Reg<string>" :
6874 { return Array . from ( cursor . regStrs ( ) ) [ 0 ] }
75+ default : { return undefined ; }
6976 }
7077 } else {
7178 // return new object if not at a leaf
@@ -102,7 +109,7 @@ const setValue = (cursor: Cursor, value: any): Causal => {
102109
103110 } else if ( typeof value == 'object' ) {
104111 // delete complete object, if table
105- if ( cursor . pointsAtTable ( ) ) {
112+ if ( pointsAtTable ( cursor . typeOf ( ) ) ) {
106113 for ( const k in cursor . keys ( ) ) {
107114 const here = cursor . clone ( )
108115 here . mapKeyStr ( k )
@@ -118,10 +125,9 @@ const setValue = (cursor: Cursor, value: any): Causal => {
118125 // add
119126 Object . entries ( value ) . forEach ( ( [ k , v ] ) => {
120127 const here = cursor . clone ( )
121- if ( here . pointsAtTable ( ) ) {
128+ if ( pointsAtTable ( here . typeOf ( ) ) ) {
122129 here . mapKeyStr ( k )
123130 } else {
124- console . log ( "structField" , k )
125131 here . structField ( k )
126132 }
127133 const c = setPrimitiveValue ( here , v )
@@ -142,10 +148,10 @@ const setValue = (cursor: Cursor, value: any): Causal => {
142148
143149const setPrimitiveValue = ( cursor : Cursor , value : any ) : Causal => {
144150
145- switch ( cursor . valueType ( ) ) {
151+ switch ( cursor . typeOf ( ) ) {
146152 case null :
147153 case "null" :
148- throw new Error ( `Not pointing at value type: ${ cursor . valueType ( ) } ` )
154+ throw new Error ( `Not pointing at value type: ${ cursor . typeOf ( ) } ` )
149155 case "bool" :
150156 if ( Boolean ( value ) ) {
151157 return cursor . flagEnable ( )
@@ -166,6 +172,11 @@ const setPrimitiveValue = (cursor: Cursor, value: any): Causal => {
166172 }
167173}
168174
175+ const pointsAtArray = ( ty : string ) : boolean => ty . startsWith ( "Array" )
176+ const pointsAtTable = ( ty : string ) : boolean => ty . startsWith ( "Table" )
177+ const pointsAtStruct = ( ty : string ) : boolean => ty . startsWith ( "Struct" )
178+ const pointsAtValue = ( ty : string ) : boolean => ! ( pointsAtArray ( ty ) || pointsAtTable ( ty ) || pointsAtStruct ( ty ) )
179+
169180const mkProxy = < T extends object > ( doc : Doc , cursor_ ?: Cursor ) : T => {
170181
171182 return new Proxy < T > ( { } as T , {
@@ -175,22 +186,21 @@ const mkProxy = <T extends object>(doc: Doc, cursor_?: Cursor): T => {
175186 // defineProperty?(target: T, p: string | symbol, attributes: PropertyDescriptor): boolean,
176187 // deleteProperty?(target: T, p: string | symbol): boolean,
177188 get ( target : T , p : string | symbol , receiver : any ) {
189+ // TODO:
178190 switch ( p ) {
179191 case Symbol . toPrimitive :
180192 case "valueOf" :
181193 return undefined
182194 case "toString" : {
183- return function ( ...args : any [ ] ) {
184- console . log ( "toString" , args )
185- return "LOL"
186- }
195+ throw new Error ( `Method ${ p } not implemented in TLFS proxy. Please file a bug and/or use the document API directly to work around.` )
187196 }
188197 }
189198
190199 const cursor = cursor_ ?. clone ( ) || doc . createCursor ( )
191- console . log ( "get" , target , p , receiver )
192200
193- if ( cursor . pointsAtArray ( ) ) {
201+ const ty = cursor . typeOf ( )
202+
203+ if ( pointsAtArray ( ty ) ) {
194204 switch ( p ) {
195205 case 'filter' : {
196206 return function ( ...args : any [ ] ) {
@@ -208,11 +218,9 @@ const mkProxy = <T extends object>(doc: Doc, cursor_?: Cursor): T => {
208218 case 'push' : {
209219 const c2 = cursor . clone ( )
210220 return function ( ...args : any [ ] ) {
211- console . log ( "pushing with" , c2 , args )
212221 if ( args . length > 0 ) {
213222 let causal : Causal | undefined ;
214223 let arrayLen = c2 . arrayLength ( )
215- console . log ( "arrayLen" , arrayLen )
216224 args . forEach ( ( v , idx ) => {
217225
218226 const c = c2 . clone ( )
@@ -233,10 +241,8 @@ const mkProxy = <T extends object>(doc: Doc, cursor_?: Cursor): T => {
233241 }
234242 case 'map' : {
235243 return function ( ...args : any [ ] ) {
236- console . log ( "map" , cursor . arrayLength ( ) )
237244 const arr = new Array ( cursor . arrayLength ( ) ) . fill ( undefined ) . map ( ( _v , idx ) => {
238245 const x = get ( doc , cursor . clone ( ) ) ( { } , idx . toString ( ) , undefined )
239- console . log ( "arr get" , idx , x )
240246 return x
241247 }
242248 )
@@ -248,8 +254,9 @@ const mkProxy = <T extends object>(doc: Doc, cursor_?: Cursor): T => {
248254 }
249255 traverse ( cursor , p )
250256
251- if ( cursor . pointsAtValue ( ) ) {
252- switch ( cursor . valueType ( ) ) {
257+ const tyAfterTraversal = cursor . typeOf ( )
258+ if ( pointsAtValue ( tyAfterTraversal ) ) {
259+ switch ( tyAfterTraversal ) {
253260 case "null" : return undefined
254261 case "bool" : return cursor . flagEnabled ( )
255262 case "Reg<bool>" :
@@ -270,23 +277,18 @@ const mkProxy = <T extends object>(doc: Doc, cursor_?: Cursor): T => {
270277 // TODO: check `p`
271278 const cursor = cursor_ ?. clone ( ) || doc . createCursor ( )
272279 const value = get ( doc , cursor ) ( target , p , undefined )
273- console . log ( "getOwnPropertDescriptor" , target , p , value )
274280 return { configurable : true , enumerable : true , value }
275281 } ,
276282 // getPrototypeOf?(target: T): object | null,
277283 // has?(target: T, p: string | symbol): boolean,
278284 // isExtensible?(target: T): boolean,
279285 ownKeys ( target : T ) : ArrayLike < string | symbol > {
280-
281- console . log ( "ownKeys" , target )
282286 const cursor = cursor_ ?. clone ( ) || doc . createCursor ( )
283287 return Array . from ( cursor . keys ( ) )
284288 } ,
285289 // preventExtensions?(target: T): boolean,
286290 set ( target : T , p : string | symbol , value : any , receiver : any ) : boolean {
287291 const cursor = cursor_ ?. clone ( ) || doc . createCursor ( )
288- console . log ( "set" , target , p , value , receiver )
289-
290292 traverse ( cursor , p )
291293
292294 const causal = setValue ( cursor , value )
0 commit comments