@tanstack/db-sqlite-persistence-core 0.4.4 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -6
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/persisted.cjs +12 -10
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/cjs/persisted.d.cts +7 -1
- package/dist/cjs/remote-subset-wire.cjs +100 -73
- package/dist/cjs/remote-subset-wire.cjs.map +1 -1
- package/dist/cjs/remote-subset-wire.d.cts +2 -0
- package/dist/cjs/sqlite-core-adapter.cjs +136 -28
- package/dist/cjs/sqlite-core-adapter.cjs.map +1 -1
- package/dist/cjs/sqlite-value.cjs +51 -0
- package/dist/cjs/sqlite-value.cjs.map +1 -1
- package/dist/cjs/sqlite-value.d.cts +12 -0
- package/dist/esm/index.js +8 -3
- package/dist/esm/persisted.d.ts +7 -1
- package/dist/esm/persisted.js +14 -12
- package/dist/esm/persisted.js.map +1 -1
- package/dist/esm/remote-subset-wire.d.ts +2 -0
- package/dist/esm/remote-subset-wire.js +101 -74
- package/dist/esm/remote-subset-wire.js.map +1 -1
- package/dist/esm/sqlite-core-adapter.js +138 -30
- package/dist/esm/sqlite-core-adapter.js.map +1 -1
- package/dist/esm/sqlite-value.d.ts +12 -0
- package/dist/esm/sqlite-value.js +53 -2
- package/dist/esm/sqlite-value.js.map +1 -1
- package/package.json +4 -3
- package/src/persisted.ts +31 -16
- package/src/remote-subset-wire.ts +149 -79
- package/src/sqlite-core-adapter.ts +221 -34
- package/src/sqlite-value.ts +98 -1
|
@@ -87,6 +87,7 @@ export class RemoteSubsetWireValueError extends TypeError {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
type ProjectionState = {
|
|
90
|
+
validateOnly: boolean
|
|
90
91
|
expressions: WeakMap<object, RemoteSubsetWireExpression>
|
|
91
92
|
expressionArrays: WeakMap<object, Array<RemoteSubsetWireExpression>>
|
|
92
93
|
stringArrays: WeakMap<object, Array<string>>
|
|
@@ -134,6 +135,20 @@ const identifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/
|
|
|
134
135
|
*/
|
|
135
136
|
export function toTransportedLoadSubsetOptions(
|
|
136
137
|
options: LoadSubsetOptions,
|
|
138
|
+
): TransportedLoadSubsetOptions {
|
|
139
|
+
return visitLoadSubsetOptions(options, false)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Checks wire admission without constructing a detached request snapshot. */
|
|
143
|
+
export function validateRemoteSubsetOptions(options: LoadSubsetOptions): void {
|
|
144
|
+
visitLoadSubsetOptions(options, true)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Both modes run the same admission checks. Validation retains input nodes only
|
|
148
|
+
// as cycle markers; it never writes to them or returns them to a caller.
|
|
149
|
+
function visitLoadSubsetOptions(
|
|
150
|
+
options: LoadSubsetOptions,
|
|
151
|
+
validateOnly: boolean,
|
|
137
152
|
): TransportedLoadSubsetOptions {
|
|
138
153
|
assertPlainContainer(options, `options`)
|
|
139
154
|
assertAllowedProperties(options, `options`, [
|
|
@@ -147,6 +162,7 @@ export function toTransportedLoadSubsetOptions(
|
|
|
147
162
|
])
|
|
148
163
|
|
|
149
164
|
const state: ProjectionState = {
|
|
165
|
+
validateOnly,
|
|
150
166
|
expressions: new WeakMap(),
|
|
151
167
|
expressionArrays: new WeakMap(),
|
|
152
168
|
stringArrays: new WeakMap(),
|
|
@@ -156,7 +172,9 @@ export function toTransportedLoadSubsetOptions(
|
|
|
156
172
|
cursors: new WeakMap(),
|
|
157
173
|
wireValues: new WeakMap(),
|
|
158
174
|
}
|
|
159
|
-
const projected: TransportedLoadSubsetOptions =
|
|
175
|
+
const projected: TransportedLoadSubsetOptions = validateOnly
|
|
176
|
+
? (options as TransportedLoadSubsetOptions)
|
|
177
|
+
: {}
|
|
160
178
|
const where = readDataProperty(options, `where`, `options.where`)
|
|
161
179
|
const orderBy = readDataProperty(options, `orderBy`, `options.orderBy`)
|
|
162
180
|
const limit = readDataProperty(options, `limit`, `options.limit`)
|
|
@@ -164,19 +182,24 @@ export function toTransportedLoadSubsetOptions(
|
|
|
164
182
|
const offset = readDataProperty(options, `offset`, `options.offset`)
|
|
165
183
|
|
|
166
184
|
if (where.present && where.value !== undefined) {
|
|
167
|
-
|
|
185
|
+
const result = projectExpression(where.value, `options.where`, state)
|
|
186
|
+
if (!state.validateOnly) projected.where = result
|
|
168
187
|
}
|
|
169
188
|
if (orderBy.present && orderBy.value !== undefined) {
|
|
170
|
-
|
|
189
|
+
const result = projectOrderBy(orderBy.value, `options.orderBy`, state)
|
|
190
|
+
if (!state.validateOnly) projected.orderBy = result
|
|
171
191
|
}
|
|
172
192
|
if (limit.present && limit.value !== undefined) {
|
|
173
|
-
|
|
193
|
+
const result = projectNumber(limit.value, `options.limit`)
|
|
194
|
+
if (!state.validateOnly) projected.limit = result
|
|
174
195
|
}
|
|
175
196
|
if (cursor.present && cursor.value !== undefined) {
|
|
176
|
-
|
|
197
|
+
const result = projectCursor(cursor.value, `options.cursor`, state)
|
|
198
|
+
if (!state.validateOnly) projected.cursor = result
|
|
177
199
|
}
|
|
178
200
|
if (offset.present && offset.value !== undefined) {
|
|
179
|
-
|
|
201
|
+
const result = projectNumber(offset.value, `options.offset`)
|
|
202
|
+
if (!state.validateOnly) projected.offset = result
|
|
180
203
|
}
|
|
181
204
|
|
|
182
205
|
return projected
|
|
@@ -228,17 +251,18 @@ function projectExpression(
|
|
|
228
251
|
case `ref`: {
|
|
229
252
|
assertExpressionPrototype(object, path, IR.PropRef.prototype)
|
|
230
253
|
assertAllowedProperties(object, path, [`type`, `path`, `sourceAlias`])
|
|
231
|
-
const projected: Extract<RemoteSubsetWireExpression, { type: `ref` }> =
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
254
|
+
const projected: Extract<RemoteSubsetWireExpression, { type: `ref` }> =
|
|
255
|
+
state.validateOnly
|
|
256
|
+
? (object as Extract<RemoteSubsetWireExpression, { type: `ref` }>)
|
|
257
|
+
: { type: `ref`, path: [] }
|
|
235
258
|
state.expressions.set(object, projected)
|
|
236
259
|
const sourcePath = readRequiredDataProperty(
|
|
237
260
|
object,
|
|
238
261
|
`path`,
|
|
239
262
|
`${path}.path`,
|
|
240
263
|
)
|
|
241
|
-
|
|
264
|
+
const result = projectStringArray(sourcePath, `${path}.path`, state)
|
|
265
|
+
if (!state.validateOnly) projected.path = result
|
|
242
266
|
const sourceAlias = readDataProperty(
|
|
243
267
|
object,
|
|
244
268
|
`sourceAlias`,
|
|
@@ -247,49 +271,50 @@ function projectExpression(
|
|
|
247
271
|
if (sourceAlias.present) {
|
|
248
272
|
if (
|
|
249
273
|
typeof sourceAlias.value !== `string` ||
|
|
250
|
-
|
|
274
|
+
result[0] !== sourceAlias.value
|
|
251
275
|
) {
|
|
252
276
|
throw new RemoteSubsetWireValueError(
|
|
253
277
|
`${path}.sourceAlias`,
|
|
254
278
|
`source alias must match the first path segment`,
|
|
255
279
|
)
|
|
256
280
|
}
|
|
257
|
-
projected.sourceAlias = sourceAlias.value
|
|
281
|
+
if (!state.validateOnly) projected.sourceAlias = sourceAlias.value
|
|
258
282
|
}
|
|
259
283
|
return projected
|
|
260
284
|
}
|
|
261
285
|
case `val`: {
|
|
262
286
|
assertExpressionPrototype(object, path, IR.Value.prototype)
|
|
263
287
|
assertAllowedProperties(object, path, [`type`, `value`])
|
|
264
|
-
const projected: Extract<RemoteSubsetWireExpression, { type: `val` }> =
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
288
|
+
const projected: Extract<RemoteSubsetWireExpression, { type: `val` }> =
|
|
289
|
+
state.validateOnly
|
|
290
|
+
? (object as Extract<RemoteSubsetWireExpression, { type: `val` }>)
|
|
291
|
+
: { type: `val`, value: undefined }
|
|
268
292
|
state.expressions.set(object, projected)
|
|
269
293
|
const sourceValue = readRequiredDataProperty(
|
|
270
294
|
object,
|
|
271
295
|
`value`,
|
|
272
296
|
`${path}.value`,
|
|
273
297
|
)
|
|
274
|
-
|
|
298
|
+
const result = projectWireValue(sourceValue, `${path}.value`, state)
|
|
299
|
+
if (!state.validateOnly) projected.value = result
|
|
275
300
|
return projected
|
|
276
301
|
}
|
|
277
302
|
case `func`: {
|
|
278
303
|
assertExpressionPrototype(object, path, IR.Func.prototype)
|
|
279
304
|
assertAllowedProperties(object, path, [`type`, `name`, `args`])
|
|
280
|
-
const projected
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
} satisfies RemoteSubsetWireExpression
|
|
305
|
+
const projected: Extract<RemoteSubsetWireExpression, { type: `func` }> =
|
|
306
|
+
state.validateOnly
|
|
307
|
+
? (object as Extract<RemoteSubsetWireExpression, { type: `func` }>)
|
|
308
|
+
: { type: `func`, name: ``, args: [] }
|
|
285
309
|
state.expressions.set(object, projected)
|
|
286
310
|
const name = readRequiredDataProperty(object, `name`, `${path}.name`)
|
|
287
311
|
if (typeof name !== `string`) {
|
|
288
312
|
throw new RemoteSubsetWireValueError(`${path}.name`, describe(name))
|
|
289
313
|
}
|
|
290
|
-
projected.name = name
|
|
314
|
+
if (!state.validateOnly) projected.name = name
|
|
291
315
|
const args = readRequiredDataProperty(object, `args`, `${path}.args`)
|
|
292
|
-
|
|
316
|
+
const result = projectExpressionArray(args, `${path}.args`, state)
|
|
317
|
+
if (!state.validateOnly) projected.args = result
|
|
293
318
|
return projected
|
|
294
319
|
}
|
|
295
320
|
default:
|
|
@@ -306,7 +331,9 @@ function projectExpressionArray(
|
|
|
306
331
|
const existing = state.expressionArrays.get(array)
|
|
307
332
|
if (existing) return existing
|
|
308
333
|
assertArrayShape(array, path)
|
|
309
|
-
const projected =
|
|
334
|
+
const projected = state.validateOnly
|
|
335
|
+
? (array as Array<RemoteSubsetWireExpression>)
|
|
336
|
+
: new Array<RemoteSubsetWireExpression>(array.length)
|
|
310
337
|
state.expressionArrays.set(array, projected)
|
|
311
338
|
for (let index = 0; index < array.length; index++) {
|
|
312
339
|
if (!(index in array)) {
|
|
@@ -315,11 +342,8 @@ function projectExpressionArray(
|
|
|
315
342
|
`missing expression`,
|
|
316
343
|
)
|
|
317
344
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
`${path}[${index}]`,
|
|
321
|
-
state,
|
|
322
|
-
)
|
|
345
|
+
const result = projectExpression(array[index], `${path}[${index}]`, state)
|
|
346
|
+
if (!state.validateOnly) projected[index] = result
|
|
323
347
|
}
|
|
324
348
|
return projected
|
|
325
349
|
}
|
|
@@ -333,14 +357,16 @@ function projectStringArray(
|
|
|
333
357
|
const existing = state.stringArrays.get(array)
|
|
334
358
|
if (existing) return existing
|
|
335
359
|
assertArrayShape(array, path)
|
|
336
|
-
const projected =
|
|
360
|
+
const projected = state.validateOnly
|
|
361
|
+
? (array as Array<string>)
|
|
362
|
+
: new Array<string>(array.length)
|
|
337
363
|
state.stringArrays.set(array, projected)
|
|
338
364
|
for (let index = 0; index < array.length; index++) {
|
|
339
365
|
const entry = array[index]
|
|
340
366
|
if (!(index in array) || typeof entry !== `string`) {
|
|
341
367
|
throw new RemoteSubsetWireValueError(`${path}[${index}]`, describe(entry))
|
|
342
368
|
}
|
|
343
|
-
projected[index] = entry
|
|
369
|
+
if (!state.validateOnly) projected[index] = entry
|
|
344
370
|
}
|
|
345
371
|
return projected
|
|
346
372
|
}
|
|
@@ -354,7 +380,9 @@ function projectOrderBy(
|
|
|
354
380
|
const existing = state.orderByArrays.get(array)
|
|
355
381
|
if (existing) return existing
|
|
356
382
|
assertArrayShape(array, path)
|
|
357
|
-
const projected =
|
|
383
|
+
const projected = state.validateOnly
|
|
384
|
+
? (array as Array<RemoteSubsetWireOrderByClause>)
|
|
385
|
+
: new Array<RemoteSubsetWireOrderByClause>(array.length)
|
|
358
386
|
state.orderByArrays.set(array, projected)
|
|
359
387
|
|
|
360
388
|
for (let index = 0; index < array.length; index++) {
|
|
@@ -362,20 +390,23 @@ function projectOrderBy(
|
|
|
362
390
|
const clause = requirePlainRecord(array[index], clausePath)
|
|
363
391
|
const existingClause = state.orderByClauses.get(clause)
|
|
364
392
|
if (existingClause) {
|
|
365
|
-
projected[index] = existingClause
|
|
393
|
+
if (!state.validateOnly) projected[index] = existingClause
|
|
366
394
|
continue
|
|
367
395
|
}
|
|
368
396
|
assertAllowedProperties(clause, clausePath, [
|
|
369
397
|
`expression`,
|
|
370
398
|
`compareOptions`,
|
|
371
399
|
])
|
|
372
|
-
const projectedClause =
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
400
|
+
const projectedClause = state.validateOnly
|
|
401
|
+
? (clause as RemoteSubsetWireOrderByClause)
|
|
402
|
+
: {
|
|
403
|
+
expression: undefined as unknown as RemoteSubsetWireExpression,
|
|
404
|
+
compareOptions:
|
|
405
|
+
undefined as unknown as RemoteSubsetWireCompareOptions,
|
|
406
|
+
}
|
|
407
|
+
if (!state.validateOnly) projected[index] = projectedClause
|
|
377
408
|
state.orderByClauses.set(clause, projectedClause)
|
|
378
|
-
|
|
409
|
+
const expression = projectExpression(
|
|
379
410
|
readRequiredDataProperty(
|
|
380
411
|
clause,
|
|
381
412
|
`expression`,
|
|
@@ -384,7 +415,7 @@ function projectOrderBy(
|
|
|
384
415
|
`${clausePath}.expression`,
|
|
385
416
|
state,
|
|
386
417
|
)
|
|
387
|
-
|
|
418
|
+
const compareOptions = projectCompareOptions(
|
|
388
419
|
readRequiredDataProperty(
|
|
389
420
|
clause,
|
|
390
421
|
`compareOptions`,
|
|
@@ -393,6 +424,10 @@ function projectOrderBy(
|
|
|
393
424
|
`${clausePath}.compareOptions`,
|
|
394
425
|
state,
|
|
395
426
|
)
|
|
427
|
+
if (!state.validateOnly) {
|
|
428
|
+
projectedClause.expression = expression
|
|
429
|
+
projectedClause.compareOptions = compareOptions
|
|
430
|
+
}
|
|
396
431
|
}
|
|
397
432
|
return projected
|
|
398
433
|
}
|
|
@@ -418,7 +453,7 @@ function projectCompareOptions(
|
|
|
418
453
|
stringSort?: `lexical` | `locale`
|
|
419
454
|
locale?: string
|
|
420
455
|
localeOptions?: RemoteSubsetWireRecord
|
|
421
|
-
} = {}
|
|
456
|
+
} = state.validateOnly ? source : {}
|
|
422
457
|
|
|
423
458
|
const direction = readRequiredDataProperty(
|
|
424
459
|
source,
|
|
@@ -431,13 +466,13 @@ function projectCompareOptions(
|
|
|
431
466
|
describe(direction),
|
|
432
467
|
)
|
|
433
468
|
}
|
|
434
|
-
projected.direction = direction
|
|
469
|
+
if (!state.validateOnly) projected.direction = direction
|
|
435
470
|
|
|
436
471
|
const nulls = readRequiredDataProperty(source, `nulls`, `${path}.nulls`)
|
|
437
472
|
if (nulls !== `first` && nulls !== `last`) {
|
|
438
473
|
throw new RemoteSubsetWireValueError(`${path}.nulls`, describe(nulls))
|
|
439
474
|
}
|
|
440
|
-
projected.nulls = nulls
|
|
475
|
+
if (!state.validateOnly) projected.nulls = nulls
|
|
441
476
|
|
|
442
477
|
const stringSort = readDataProperty(
|
|
443
478
|
source,
|
|
@@ -451,7 +486,7 @@ function projectCompareOptions(
|
|
|
451
486
|
describe(stringSort.value),
|
|
452
487
|
)
|
|
453
488
|
}
|
|
454
|
-
projected.stringSort = stringSort.value
|
|
489
|
+
if (!state.validateOnly) projected.stringSort = stringSort.value
|
|
455
490
|
}
|
|
456
491
|
if (projected.stringSort !== `lexical`) {
|
|
457
492
|
const locale = readDataProperty(source, `locale`, `${path}.locale`)
|
|
@@ -462,7 +497,7 @@ function projectCompareOptions(
|
|
|
462
497
|
describe(locale.value),
|
|
463
498
|
)
|
|
464
499
|
}
|
|
465
|
-
projected.locale = locale.value
|
|
500
|
+
if (!state.validateOnly) projected.locale = locale.value
|
|
466
501
|
}
|
|
467
502
|
const localeOptions = readDataProperty(
|
|
468
503
|
source,
|
|
@@ -470,11 +505,12 @@ function projectCompareOptions(
|
|
|
470
505
|
`${path}.localeOptions`,
|
|
471
506
|
)
|
|
472
507
|
if (localeOptions.present && localeOptions.value !== undefined) {
|
|
473
|
-
|
|
508
|
+
const result = projectWireRecord(
|
|
474
509
|
localeOptions.value,
|
|
475
510
|
`${path}.localeOptions`,
|
|
476
511
|
state,
|
|
477
512
|
)
|
|
513
|
+
if (!state.validateOnly) projected.localeOptions = result
|
|
478
514
|
}
|
|
479
515
|
}
|
|
480
516
|
const result = projected as RemoteSubsetWireCompareOptions
|
|
@@ -495,21 +531,27 @@ function projectCursor(
|
|
|
495
531
|
`whereCurrent`,
|
|
496
532
|
`lastKey`,
|
|
497
533
|
])
|
|
498
|
-
const projected: RemoteSubsetWireCursor =
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
534
|
+
const projected: RemoteSubsetWireCursor = state.validateOnly
|
|
535
|
+
? (source as RemoteSubsetWireCursor)
|
|
536
|
+
: {
|
|
537
|
+
whereFrom: undefined as unknown as RemoteSubsetWireExpression,
|
|
538
|
+
whereCurrent: undefined as unknown as RemoteSubsetWireExpression,
|
|
539
|
+
}
|
|
502
540
|
state.cursors.set(source, projected)
|
|
503
|
-
|
|
541
|
+
const whereFrom = projectExpression(
|
|
504
542
|
readRequiredDataProperty(source, `whereFrom`, `${path}.whereFrom`),
|
|
505
543
|
`${path}.whereFrom`,
|
|
506
544
|
state,
|
|
507
545
|
)
|
|
508
|
-
|
|
546
|
+
const whereCurrent = projectExpression(
|
|
509
547
|
readRequiredDataProperty(source, `whereCurrent`, `${path}.whereCurrent`),
|
|
510
548
|
`${path}.whereCurrent`,
|
|
511
549
|
state,
|
|
512
550
|
)
|
|
551
|
+
if (!state.validateOnly) {
|
|
552
|
+
projected.whereFrom = whereFrom
|
|
553
|
+
projected.whereCurrent = whereCurrent
|
|
554
|
+
}
|
|
513
555
|
const lastKey = readDataProperty(source, `lastKey`, `${path}.lastKey`)
|
|
514
556
|
if (lastKey.present && lastKey.value !== undefined) {
|
|
515
557
|
if (
|
|
@@ -521,7 +563,7 @@ function projectCursor(
|
|
|
521
563
|
describe(lastKey.value),
|
|
522
564
|
)
|
|
523
565
|
}
|
|
524
|
-
projected.lastKey = lastKey.value
|
|
566
|
+
if (!state.validateOnly) projected.lastKey = lastKey.value
|
|
525
567
|
}
|
|
526
568
|
return projected
|
|
527
569
|
}
|
|
@@ -557,14 +599,16 @@ function projectWireValue(
|
|
|
557
599
|
if (value instanceof NativeDate) {
|
|
558
600
|
assertExactPrototype(value, NativeDate.prototype, path)
|
|
559
601
|
assertNoOwnProperties(value, path)
|
|
560
|
-
const
|
|
602
|
+
const time = value.getTime()
|
|
603
|
+
const projected = state.validateOnly ? value : new NativeDate(time)
|
|
561
604
|
state.wireValues.set(value, projected)
|
|
562
605
|
return projected
|
|
563
606
|
}
|
|
564
607
|
if (value instanceof RegExp) {
|
|
565
608
|
assertExactPrototype(value, RegExp.prototype, path)
|
|
566
609
|
assertRegExpShape(value, path)
|
|
567
|
-
const
|
|
610
|
+
const { source, flags } = value
|
|
611
|
+
const projected = state.validateOnly ? value : new RegExp(source, flags)
|
|
568
612
|
state.wireValues.set(value, projected)
|
|
569
613
|
return projected
|
|
570
614
|
}
|
|
@@ -574,7 +618,13 @@ function projectWireValue(
|
|
|
574
618
|
assertFixedArrayBuffer(value, path)
|
|
575
619
|
let projected: ArrayBuffer
|
|
576
620
|
try {
|
|
577
|
-
|
|
621
|
+
if (state.validateOnly) {
|
|
622
|
+
// A zero-length view checks detachment without copying the backing bytes.
|
|
623
|
+
new Uint8Array(value, 0, 0)
|
|
624
|
+
projected = value
|
|
625
|
+
} else {
|
|
626
|
+
projected = value.slice(0)
|
|
627
|
+
}
|
|
578
628
|
} catch {
|
|
579
629
|
throw new RemoteSubsetWireValueError(path, `detached ArrayBuffer`)
|
|
580
630
|
}
|
|
@@ -598,7 +648,9 @@ function projectWireValue(
|
|
|
598
648
|
if (!(projectedBuffer instanceof ArrayBuffer)) {
|
|
599
649
|
throw new RemoteSubsetWireValueError(path, `shared DataView buffer`)
|
|
600
650
|
}
|
|
601
|
-
const projected =
|
|
651
|
+
const projected = state.validateOnly
|
|
652
|
+
? value
|
|
653
|
+
: new DataView(projectedBuffer, byteOffset, byteLength)
|
|
602
654
|
state.wireValues.set(value, projected)
|
|
603
655
|
return projected
|
|
604
656
|
}
|
|
@@ -626,7 +678,9 @@ function projectWireValue(
|
|
|
626
678
|
}
|
|
627
679
|
let projected: RemoteSubsetWireTypedArray
|
|
628
680
|
try {
|
|
629
|
-
projected =
|
|
681
|
+
projected = state.validateOnly
|
|
682
|
+
? typedArray
|
|
683
|
+
: new typedArrayConstructor(projectedBuffer, byteOffset, length)
|
|
630
684
|
} catch {
|
|
631
685
|
throw new RemoteSubsetWireValueError(path, `detached typed array`)
|
|
632
686
|
}
|
|
@@ -648,15 +702,14 @@ function projectWireArray(
|
|
|
648
702
|
state: ProjectionState,
|
|
649
703
|
): Array<RemoteSubsetWireValue> {
|
|
650
704
|
assertArrayShape(value, path)
|
|
651
|
-
const projected =
|
|
705
|
+
const projected = state.validateOnly
|
|
706
|
+
? (value as Array<RemoteSubsetWireValue>)
|
|
707
|
+
: new Array<RemoteSubsetWireValue>(value.length)
|
|
652
708
|
state.wireValues.set(value, projected)
|
|
653
709
|
for (let index = 0; index < value.length; index++) {
|
|
654
710
|
if (index in value) {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
`${path}[${index}]`,
|
|
658
|
-
state,
|
|
659
|
-
)
|
|
711
|
+
const result = projectWireValue(value[index], `${path}[${index}]`, state)
|
|
712
|
+
if (!state.validateOnly) projected[index] = result
|
|
660
713
|
}
|
|
661
714
|
}
|
|
662
715
|
return projected
|
|
@@ -669,14 +722,23 @@ function projectWireMap(
|
|
|
669
722
|
): Map<RemoteSubsetWireValue, RemoteSubsetWireValue> {
|
|
670
723
|
assertExactPrototype(value, Map.prototype, path)
|
|
671
724
|
assertNoOwnProperties(value, path)
|
|
672
|
-
const projected =
|
|
725
|
+
const projected = state.validateOnly
|
|
726
|
+
? (value as Map<RemoteSubsetWireValue, RemoteSubsetWireValue>)
|
|
727
|
+
: new Map<RemoteSubsetWireValue, RemoteSubsetWireValue>()
|
|
673
728
|
state.wireValues.set(value, projected)
|
|
674
729
|
let index = 0
|
|
675
730
|
for (const [key, entry] of value) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
731
|
+
const projectedKey = projectWireValue(
|
|
732
|
+
key,
|
|
733
|
+
`${path}.entries[${index}].key`,
|
|
734
|
+
state,
|
|
679
735
|
)
|
|
736
|
+
const projectedValue = projectWireValue(
|
|
737
|
+
entry,
|
|
738
|
+
`${path}.entries[${index}].value`,
|
|
739
|
+
state,
|
|
740
|
+
)
|
|
741
|
+
if (!state.validateOnly) projected.set(projectedKey, projectedValue)
|
|
680
742
|
index++
|
|
681
743
|
}
|
|
682
744
|
return projected
|
|
@@ -689,11 +751,14 @@ function projectWireSet(
|
|
|
689
751
|
): Set<RemoteSubsetWireValue> {
|
|
690
752
|
assertExactPrototype(value, Set.prototype, path)
|
|
691
753
|
assertNoOwnProperties(value, path)
|
|
692
|
-
const projected =
|
|
754
|
+
const projected = state.validateOnly
|
|
755
|
+
? (value as Set<RemoteSubsetWireValue>)
|
|
756
|
+
: new Set<RemoteSubsetWireValue>()
|
|
693
757
|
state.wireValues.set(value, projected)
|
|
694
758
|
let index = 0
|
|
695
759
|
for (const entry of value) {
|
|
696
|
-
|
|
760
|
+
const result = projectWireValue(entry, `${path}.values[${index}]`, state)
|
|
761
|
+
if (!state.validateOnly) projected.add(result)
|
|
697
762
|
index++
|
|
698
763
|
}
|
|
699
764
|
return projected
|
|
@@ -707,7 +772,9 @@ function projectWireRecord(
|
|
|
707
772
|
const source = requirePlainRecord(value, path)
|
|
708
773
|
const existing = state.wireValues.get(source)
|
|
709
774
|
if (existing) return existing as RemoteSubsetWireRecord
|
|
710
|
-
const projected: RemoteSubsetWireRecord =
|
|
775
|
+
const projected: RemoteSubsetWireRecord = state.validateOnly
|
|
776
|
+
? (source as RemoteSubsetWireRecord)
|
|
777
|
+
: {}
|
|
711
778
|
state.wireValues.set(source, projected)
|
|
712
779
|
|
|
713
780
|
for (const key of ownKeys(source, path)) {
|
|
@@ -719,12 +786,15 @@ function projectWireRecord(
|
|
|
719
786
|
if (!descriptor || !descriptor.enumerable || !(`value` in descriptor)) {
|
|
720
787
|
throw new RemoteSubsetWireValueError(childPath, `non-data property`)
|
|
721
788
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
789
|
+
const result = projectWireValue(descriptor.value, childPath, state)
|
|
790
|
+
if (!state.validateOnly) {
|
|
791
|
+
Object.defineProperty(projected, key, {
|
|
792
|
+
value: result,
|
|
793
|
+
enumerable: true,
|
|
794
|
+
writable: true,
|
|
795
|
+
configurable: true,
|
|
796
|
+
})
|
|
797
|
+
}
|
|
728
798
|
}
|
|
729
799
|
return projected
|
|
730
800
|
}
|