@tanstack/db-sqlite-persistence-core 0.4.3 → 0.4.5
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/errors.cjs.map +1 -1
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/persisted.cjs +59 -62
- 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 +433 -184
- 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/errors.js.map +1 -1
- package/dist/esm/index.js +8 -3
- package/dist/esm/persisted.d.ts +7 -1
- package/dist/esm/persisted.js +63 -66
- 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 +435 -186
- 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/errors.ts +1 -2
- package/src/persisted.ts +111 -91
- package/src/remote-subset-wire.ts +150 -85
- package/src/sqlite-core-adapter.ts +686 -235
- package/src/sqlite-value.ts +98 -1
|
@@ -2,12 +2,7 @@ import { IR } from '@tanstack/db'
|
|
|
2
2
|
import type { LoadSubsetOptions } from '@tanstack/db'
|
|
3
3
|
|
|
4
4
|
export type RemoteSubsetWirePrimitive =
|
|
5
|
-
|
|
|
6
|
-
| null
|
|
7
|
-
| boolean
|
|
8
|
-
| string
|
|
9
|
-
| number
|
|
10
|
-
| bigint
|
|
5
|
+
undefined | null | boolean | string | number | bigint
|
|
11
6
|
|
|
12
7
|
export type RemoteSubsetWireTypedArray =
|
|
13
8
|
| Int8Array
|
|
@@ -92,6 +87,7 @@ export class RemoteSubsetWireValueError extends TypeError {
|
|
|
92
87
|
}
|
|
93
88
|
|
|
94
89
|
type ProjectionState = {
|
|
90
|
+
validateOnly: boolean
|
|
95
91
|
expressions: WeakMap<object, RemoteSubsetWireExpression>
|
|
96
92
|
expressionArrays: WeakMap<object, Array<RemoteSubsetWireExpression>>
|
|
97
93
|
stringArrays: WeakMap<object, Array<string>>
|
|
@@ -139,6 +135,20 @@ const identifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/
|
|
|
139
135
|
*/
|
|
140
136
|
export function toTransportedLoadSubsetOptions(
|
|
141
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,
|
|
142
152
|
): TransportedLoadSubsetOptions {
|
|
143
153
|
assertPlainContainer(options, `options`)
|
|
144
154
|
assertAllowedProperties(options, `options`, [
|
|
@@ -152,6 +162,7 @@ export function toTransportedLoadSubsetOptions(
|
|
|
152
162
|
])
|
|
153
163
|
|
|
154
164
|
const state: ProjectionState = {
|
|
165
|
+
validateOnly,
|
|
155
166
|
expressions: new WeakMap(),
|
|
156
167
|
expressionArrays: new WeakMap(),
|
|
157
168
|
stringArrays: new WeakMap(),
|
|
@@ -161,7 +172,9 @@ export function toTransportedLoadSubsetOptions(
|
|
|
161
172
|
cursors: new WeakMap(),
|
|
162
173
|
wireValues: new WeakMap(),
|
|
163
174
|
}
|
|
164
|
-
const projected: TransportedLoadSubsetOptions =
|
|
175
|
+
const projected: TransportedLoadSubsetOptions = validateOnly
|
|
176
|
+
? (options as TransportedLoadSubsetOptions)
|
|
177
|
+
: {}
|
|
165
178
|
const where = readDataProperty(options, `where`, `options.where`)
|
|
166
179
|
const orderBy = readDataProperty(options, `orderBy`, `options.orderBy`)
|
|
167
180
|
const limit = readDataProperty(options, `limit`, `options.limit`)
|
|
@@ -169,19 +182,24 @@ export function toTransportedLoadSubsetOptions(
|
|
|
169
182
|
const offset = readDataProperty(options, `offset`, `options.offset`)
|
|
170
183
|
|
|
171
184
|
if (where.present && where.value !== undefined) {
|
|
172
|
-
|
|
185
|
+
const result = projectExpression(where.value, `options.where`, state)
|
|
186
|
+
if (!state.validateOnly) projected.where = result
|
|
173
187
|
}
|
|
174
188
|
if (orderBy.present && orderBy.value !== undefined) {
|
|
175
|
-
|
|
189
|
+
const result = projectOrderBy(orderBy.value, `options.orderBy`, state)
|
|
190
|
+
if (!state.validateOnly) projected.orderBy = result
|
|
176
191
|
}
|
|
177
192
|
if (limit.present && limit.value !== undefined) {
|
|
178
|
-
|
|
193
|
+
const result = projectNumber(limit.value, `options.limit`)
|
|
194
|
+
if (!state.validateOnly) projected.limit = result
|
|
179
195
|
}
|
|
180
196
|
if (cursor.present && cursor.value !== undefined) {
|
|
181
|
-
|
|
197
|
+
const result = projectCursor(cursor.value, `options.cursor`, state)
|
|
198
|
+
if (!state.validateOnly) projected.cursor = result
|
|
182
199
|
}
|
|
183
200
|
if (offset.present && offset.value !== undefined) {
|
|
184
|
-
|
|
201
|
+
const result = projectNumber(offset.value, `options.offset`)
|
|
202
|
+
if (!state.validateOnly) projected.offset = result
|
|
185
203
|
}
|
|
186
204
|
|
|
187
205
|
return projected
|
|
@@ -233,17 +251,18 @@ function projectExpression(
|
|
|
233
251
|
case `ref`: {
|
|
234
252
|
assertExpressionPrototype(object, path, IR.PropRef.prototype)
|
|
235
253
|
assertAllowedProperties(object, path, [`type`, `path`, `sourceAlias`])
|
|
236
|
-
const projected: Extract<RemoteSubsetWireExpression, { type: `ref` }> =
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
254
|
+
const projected: Extract<RemoteSubsetWireExpression, { type: `ref` }> =
|
|
255
|
+
state.validateOnly
|
|
256
|
+
? (object as Extract<RemoteSubsetWireExpression, { type: `ref` }>)
|
|
257
|
+
: { type: `ref`, path: [] }
|
|
240
258
|
state.expressions.set(object, projected)
|
|
241
259
|
const sourcePath = readRequiredDataProperty(
|
|
242
260
|
object,
|
|
243
261
|
`path`,
|
|
244
262
|
`${path}.path`,
|
|
245
263
|
)
|
|
246
|
-
|
|
264
|
+
const result = projectStringArray(sourcePath, `${path}.path`, state)
|
|
265
|
+
if (!state.validateOnly) projected.path = result
|
|
247
266
|
const sourceAlias = readDataProperty(
|
|
248
267
|
object,
|
|
249
268
|
`sourceAlias`,
|
|
@@ -252,49 +271,50 @@ function projectExpression(
|
|
|
252
271
|
if (sourceAlias.present) {
|
|
253
272
|
if (
|
|
254
273
|
typeof sourceAlias.value !== `string` ||
|
|
255
|
-
|
|
274
|
+
result[0] !== sourceAlias.value
|
|
256
275
|
) {
|
|
257
276
|
throw new RemoteSubsetWireValueError(
|
|
258
277
|
`${path}.sourceAlias`,
|
|
259
278
|
`source alias must match the first path segment`,
|
|
260
279
|
)
|
|
261
280
|
}
|
|
262
|
-
projected.sourceAlias = sourceAlias.value
|
|
281
|
+
if (!state.validateOnly) projected.sourceAlias = sourceAlias.value
|
|
263
282
|
}
|
|
264
283
|
return projected
|
|
265
284
|
}
|
|
266
285
|
case `val`: {
|
|
267
286
|
assertExpressionPrototype(object, path, IR.Value.prototype)
|
|
268
287
|
assertAllowedProperties(object, path, [`type`, `value`])
|
|
269
|
-
const projected: Extract<RemoteSubsetWireExpression, { type: `val` }> =
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
288
|
+
const projected: Extract<RemoteSubsetWireExpression, { type: `val` }> =
|
|
289
|
+
state.validateOnly
|
|
290
|
+
? (object as Extract<RemoteSubsetWireExpression, { type: `val` }>)
|
|
291
|
+
: { type: `val`, value: undefined }
|
|
273
292
|
state.expressions.set(object, projected)
|
|
274
293
|
const sourceValue = readRequiredDataProperty(
|
|
275
294
|
object,
|
|
276
295
|
`value`,
|
|
277
296
|
`${path}.value`,
|
|
278
297
|
)
|
|
279
|
-
|
|
298
|
+
const result = projectWireValue(sourceValue, `${path}.value`, state)
|
|
299
|
+
if (!state.validateOnly) projected.value = result
|
|
280
300
|
return projected
|
|
281
301
|
}
|
|
282
302
|
case `func`: {
|
|
283
303
|
assertExpressionPrototype(object, path, IR.Func.prototype)
|
|
284
304
|
assertAllowedProperties(object, path, [`type`, `name`, `args`])
|
|
285
|
-
const projected
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
} satisfies RemoteSubsetWireExpression
|
|
305
|
+
const projected: Extract<RemoteSubsetWireExpression, { type: `func` }> =
|
|
306
|
+
state.validateOnly
|
|
307
|
+
? (object as Extract<RemoteSubsetWireExpression, { type: `func` }>)
|
|
308
|
+
: { type: `func`, name: ``, args: [] }
|
|
290
309
|
state.expressions.set(object, projected)
|
|
291
310
|
const name = readRequiredDataProperty(object, `name`, `${path}.name`)
|
|
292
311
|
if (typeof name !== `string`) {
|
|
293
312
|
throw new RemoteSubsetWireValueError(`${path}.name`, describe(name))
|
|
294
313
|
}
|
|
295
|
-
projected.name = name
|
|
314
|
+
if (!state.validateOnly) projected.name = name
|
|
296
315
|
const args = readRequiredDataProperty(object, `args`, `${path}.args`)
|
|
297
|
-
|
|
316
|
+
const result = projectExpressionArray(args, `${path}.args`, state)
|
|
317
|
+
if (!state.validateOnly) projected.args = result
|
|
298
318
|
return projected
|
|
299
319
|
}
|
|
300
320
|
default:
|
|
@@ -311,7 +331,9 @@ function projectExpressionArray(
|
|
|
311
331
|
const existing = state.expressionArrays.get(array)
|
|
312
332
|
if (existing) return existing
|
|
313
333
|
assertArrayShape(array, path)
|
|
314
|
-
const projected =
|
|
334
|
+
const projected = state.validateOnly
|
|
335
|
+
? (array as Array<RemoteSubsetWireExpression>)
|
|
336
|
+
: new Array<RemoteSubsetWireExpression>(array.length)
|
|
315
337
|
state.expressionArrays.set(array, projected)
|
|
316
338
|
for (let index = 0; index < array.length; index++) {
|
|
317
339
|
if (!(index in array)) {
|
|
@@ -320,11 +342,8 @@ function projectExpressionArray(
|
|
|
320
342
|
`missing expression`,
|
|
321
343
|
)
|
|
322
344
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
`${path}[${index}]`,
|
|
326
|
-
state,
|
|
327
|
-
)
|
|
345
|
+
const result = projectExpression(array[index], `${path}[${index}]`, state)
|
|
346
|
+
if (!state.validateOnly) projected[index] = result
|
|
328
347
|
}
|
|
329
348
|
return projected
|
|
330
349
|
}
|
|
@@ -338,14 +357,16 @@ function projectStringArray(
|
|
|
338
357
|
const existing = state.stringArrays.get(array)
|
|
339
358
|
if (existing) return existing
|
|
340
359
|
assertArrayShape(array, path)
|
|
341
|
-
const projected =
|
|
360
|
+
const projected = state.validateOnly
|
|
361
|
+
? (array as Array<string>)
|
|
362
|
+
: new Array<string>(array.length)
|
|
342
363
|
state.stringArrays.set(array, projected)
|
|
343
364
|
for (let index = 0; index < array.length; index++) {
|
|
344
365
|
const entry = array[index]
|
|
345
366
|
if (!(index in array) || typeof entry !== `string`) {
|
|
346
367
|
throw new RemoteSubsetWireValueError(`${path}[${index}]`, describe(entry))
|
|
347
368
|
}
|
|
348
|
-
projected[index] = entry
|
|
369
|
+
if (!state.validateOnly) projected[index] = entry
|
|
349
370
|
}
|
|
350
371
|
return projected
|
|
351
372
|
}
|
|
@@ -359,7 +380,9 @@ function projectOrderBy(
|
|
|
359
380
|
const existing = state.orderByArrays.get(array)
|
|
360
381
|
if (existing) return existing
|
|
361
382
|
assertArrayShape(array, path)
|
|
362
|
-
const projected =
|
|
383
|
+
const projected = state.validateOnly
|
|
384
|
+
? (array as Array<RemoteSubsetWireOrderByClause>)
|
|
385
|
+
: new Array<RemoteSubsetWireOrderByClause>(array.length)
|
|
363
386
|
state.orderByArrays.set(array, projected)
|
|
364
387
|
|
|
365
388
|
for (let index = 0; index < array.length; index++) {
|
|
@@ -367,20 +390,23 @@ function projectOrderBy(
|
|
|
367
390
|
const clause = requirePlainRecord(array[index], clausePath)
|
|
368
391
|
const existingClause = state.orderByClauses.get(clause)
|
|
369
392
|
if (existingClause) {
|
|
370
|
-
projected[index] = existingClause
|
|
393
|
+
if (!state.validateOnly) projected[index] = existingClause
|
|
371
394
|
continue
|
|
372
395
|
}
|
|
373
396
|
assertAllowedProperties(clause, clausePath, [
|
|
374
397
|
`expression`,
|
|
375
398
|
`compareOptions`,
|
|
376
399
|
])
|
|
377
|
-
const projectedClause =
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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
|
|
382
408
|
state.orderByClauses.set(clause, projectedClause)
|
|
383
|
-
|
|
409
|
+
const expression = projectExpression(
|
|
384
410
|
readRequiredDataProperty(
|
|
385
411
|
clause,
|
|
386
412
|
`expression`,
|
|
@@ -389,7 +415,7 @@ function projectOrderBy(
|
|
|
389
415
|
`${clausePath}.expression`,
|
|
390
416
|
state,
|
|
391
417
|
)
|
|
392
|
-
|
|
418
|
+
const compareOptions = projectCompareOptions(
|
|
393
419
|
readRequiredDataProperty(
|
|
394
420
|
clause,
|
|
395
421
|
`compareOptions`,
|
|
@@ -398,6 +424,10 @@ function projectOrderBy(
|
|
|
398
424
|
`${clausePath}.compareOptions`,
|
|
399
425
|
state,
|
|
400
426
|
)
|
|
427
|
+
if (!state.validateOnly) {
|
|
428
|
+
projectedClause.expression = expression
|
|
429
|
+
projectedClause.compareOptions = compareOptions
|
|
430
|
+
}
|
|
401
431
|
}
|
|
402
432
|
return projected
|
|
403
433
|
}
|
|
@@ -423,7 +453,7 @@ function projectCompareOptions(
|
|
|
423
453
|
stringSort?: `lexical` | `locale`
|
|
424
454
|
locale?: string
|
|
425
455
|
localeOptions?: RemoteSubsetWireRecord
|
|
426
|
-
} = {}
|
|
456
|
+
} = state.validateOnly ? source : {}
|
|
427
457
|
|
|
428
458
|
const direction = readRequiredDataProperty(
|
|
429
459
|
source,
|
|
@@ -436,13 +466,13 @@ function projectCompareOptions(
|
|
|
436
466
|
describe(direction),
|
|
437
467
|
)
|
|
438
468
|
}
|
|
439
|
-
projected.direction = direction
|
|
469
|
+
if (!state.validateOnly) projected.direction = direction
|
|
440
470
|
|
|
441
471
|
const nulls = readRequiredDataProperty(source, `nulls`, `${path}.nulls`)
|
|
442
472
|
if (nulls !== `first` && nulls !== `last`) {
|
|
443
473
|
throw new RemoteSubsetWireValueError(`${path}.nulls`, describe(nulls))
|
|
444
474
|
}
|
|
445
|
-
projected.nulls = nulls
|
|
475
|
+
if (!state.validateOnly) projected.nulls = nulls
|
|
446
476
|
|
|
447
477
|
const stringSort = readDataProperty(
|
|
448
478
|
source,
|
|
@@ -456,7 +486,7 @@ function projectCompareOptions(
|
|
|
456
486
|
describe(stringSort.value),
|
|
457
487
|
)
|
|
458
488
|
}
|
|
459
|
-
projected.stringSort = stringSort.value
|
|
489
|
+
if (!state.validateOnly) projected.stringSort = stringSort.value
|
|
460
490
|
}
|
|
461
491
|
if (projected.stringSort !== `lexical`) {
|
|
462
492
|
const locale = readDataProperty(source, `locale`, `${path}.locale`)
|
|
@@ -467,7 +497,7 @@ function projectCompareOptions(
|
|
|
467
497
|
describe(locale.value),
|
|
468
498
|
)
|
|
469
499
|
}
|
|
470
|
-
projected.locale = locale.value
|
|
500
|
+
if (!state.validateOnly) projected.locale = locale.value
|
|
471
501
|
}
|
|
472
502
|
const localeOptions = readDataProperty(
|
|
473
503
|
source,
|
|
@@ -475,11 +505,12 @@ function projectCompareOptions(
|
|
|
475
505
|
`${path}.localeOptions`,
|
|
476
506
|
)
|
|
477
507
|
if (localeOptions.present && localeOptions.value !== undefined) {
|
|
478
|
-
|
|
508
|
+
const result = projectWireRecord(
|
|
479
509
|
localeOptions.value,
|
|
480
510
|
`${path}.localeOptions`,
|
|
481
511
|
state,
|
|
482
512
|
)
|
|
513
|
+
if (!state.validateOnly) projected.localeOptions = result
|
|
483
514
|
}
|
|
484
515
|
}
|
|
485
516
|
const result = projected as RemoteSubsetWireCompareOptions
|
|
@@ -500,21 +531,27 @@ function projectCursor(
|
|
|
500
531
|
`whereCurrent`,
|
|
501
532
|
`lastKey`,
|
|
502
533
|
])
|
|
503
|
-
const projected: RemoteSubsetWireCursor =
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
+
}
|
|
507
540
|
state.cursors.set(source, projected)
|
|
508
|
-
|
|
541
|
+
const whereFrom = projectExpression(
|
|
509
542
|
readRequiredDataProperty(source, `whereFrom`, `${path}.whereFrom`),
|
|
510
543
|
`${path}.whereFrom`,
|
|
511
544
|
state,
|
|
512
545
|
)
|
|
513
|
-
|
|
546
|
+
const whereCurrent = projectExpression(
|
|
514
547
|
readRequiredDataProperty(source, `whereCurrent`, `${path}.whereCurrent`),
|
|
515
548
|
`${path}.whereCurrent`,
|
|
516
549
|
state,
|
|
517
550
|
)
|
|
551
|
+
if (!state.validateOnly) {
|
|
552
|
+
projected.whereFrom = whereFrom
|
|
553
|
+
projected.whereCurrent = whereCurrent
|
|
554
|
+
}
|
|
518
555
|
const lastKey = readDataProperty(source, `lastKey`, `${path}.lastKey`)
|
|
519
556
|
if (lastKey.present && lastKey.value !== undefined) {
|
|
520
557
|
if (
|
|
@@ -526,7 +563,7 @@ function projectCursor(
|
|
|
526
563
|
describe(lastKey.value),
|
|
527
564
|
)
|
|
528
565
|
}
|
|
529
|
-
projected.lastKey = lastKey.value
|
|
566
|
+
if (!state.validateOnly) projected.lastKey = lastKey.value
|
|
530
567
|
}
|
|
531
568
|
return projected
|
|
532
569
|
}
|
|
@@ -562,14 +599,16 @@ function projectWireValue(
|
|
|
562
599
|
if (value instanceof NativeDate) {
|
|
563
600
|
assertExactPrototype(value, NativeDate.prototype, path)
|
|
564
601
|
assertNoOwnProperties(value, path)
|
|
565
|
-
const
|
|
602
|
+
const time = value.getTime()
|
|
603
|
+
const projected = state.validateOnly ? value : new NativeDate(time)
|
|
566
604
|
state.wireValues.set(value, projected)
|
|
567
605
|
return projected
|
|
568
606
|
}
|
|
569
607
|
if (value instanceof RegExp) {
|
|
570
608
|
assertExactPrototype(value, RegExp.prototype, path)
|
|
571
609
|
assertRegExpShape(value, path)
|
|
572
|
-
const
|
|
610
|
+
const { source, flags } = value
|
|
611
|
+
const projected = state.validateOnly ? value : new RegExp(source, flags)
|
|
573
612
|
state.wireValues.set(value, projected)
|
|
574
613
|
return projected
|
|
575
614
|
}
|
|
@@ -579,7 +618,13 @@ function projectWireValue(
|
|
|
579
618
|
assertFixedArrayBuffer(value, path)
|
|
580
619
|
let projected: ArrayBuffer
|
|
581
620
|
try {
|
|
582
|
-
|
|
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
|
+
}
|
|
583
628
|
} catch {
|
|
584
629
|
throw new RemoteSubsetWireValueError(path, `detached ArrayBuffer`)
|
|
585
630
|
}
|
|
@@ -603,7 +648,9 @@ function projectWireValue(
|
|
|
603
648
|
if (!(projectedBuffer instanceof ArrayBuffer)) {
|
|
604
649
|
throw new RemoteSubsetWireValueError(path, `shared DataView buffer`)
|
|
605
650
|
}
|
|
606
|
-
const projected =
|
|
651
|
+
const projected = state.validateOnly
|
|
652
|
+
? value
|
|
653
|
+
: new DataView(projectedBuffer, byteOffset, byteLength)
|
|
607
654
|
state.wireValues.set(value, projected)
|
|
608
655
|
return projected
|
|
609
656
|
}
|
|
@@ -631,7 +678,9 @@ function projectWireValue(
|
|
|
631
678
|
}
|
|
632
679
|
let projected: RemoteSubsetWireTypedArray
|
|
633
680
|
try {
|
|
634
|
-
projected =
|
|
681
|
+
projected = state.validateOnly
|
|
682
|
+
? typedArray
|
|
683
|
+
: new typedArrayConstructor(projectedBuffer, byteOffset, length)
|
|
635
684
|
} catch {
|
|
636
685
|
throw new RemoteSubsetWireValueError(path, `detached typed array`)
|
|
637
686
|
}
|
|
@@ -653,15 +702,14 @@ function projectWireArray(
|
|
|
653
702
|
state: ProjectionState,
|
|
654
703
|
): Array<RemoteSubsetWireValue> {
|
|
655
704
|
assertArrayShape(value, path)
|
|
656
|
-
const projected =
|
|
705
|
+
const projected = state.validateOnly
|
|
706
|
+
? (value as Array<RemoteSubsetWireValue>)
|
|
707
|
+
: new Array<RemoteSubsetWireValue>(value.length)
|
|
657
708
|
state.wireValues.set(value, projected)
|
|
658
709
|
for (let index = 0; index < value.length; index++) {
|
|
659
710
|
if (index in value) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
`${path}[${index}]`,
|
|
663
|
-
state,
|
|
664
|
-
)
|
|
711
|
+
const result = projectWireValue(value[index], `${path}[${index}]`, state)
|
|
712
|
+
if (!state.validateOnly) projected[index] = result
|
|
665
713
|
}
|
|
666
714
|
}
|
|
667
715
|
return projected
|
|
@@ -674,14 +722,23 @@ function projectWireMap(
|
|
|
674
722
|
): Map<RemoteSubsetWireValue, RemoteSubsetWireValue> {
|
|
675
723
|
assertExactPrototype(value, Map.prototype, path)
|
|
676
724
|
assertNoOwnProperties(value, path)
|
|
677
|
-
const projected =
|
|
725
|
+
const projected = state.validateOnly
|
|
726
|
+
? (value as Map<RemoteSubsetWireValue, RemoteSubsetWireValue>)
|
|
727
|
+
: new Map<RemoteSubsetWireValue, RemoteSubsetWireValue>()
|
|
678
728
|
state.wireValues.set(value, projected)
|
|
679
729
|
let index = 0
|
|
680
730
|
for (const [key, entry] of value) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
731
|
+
const projectedKey = projectWireValue(
|
|
732
|
+
key,
|
|
733
|
+
`${path}.entries[${index}].key`,
|
|
734
|
+
state,
|
|
684
735
|
)
|
|
736
|
+
const projectedValue = projectWireValue(
|
|
737
|
+
entry,
|
|
738
|
+
`${path}.entries[${index}].value`,
|
|
739
|
+
state,
|
|
740
|
+
)
|
|
741
|
+
if (!state.validateOnly) projected.set(projectedKey, projectedValue)
|
|
685
742
|
index++
|
|
686
743
|
}
|
|
687
744
|
return projected
|
|
@@ -694,11 +751,14 @@ function projectWireSet(
|
|
|
694
751
|
): Set<RemoteSubsetWireValue> {
|
|
695
752
|
assertExactPrototype(value, Set.prototype, path)
|
|
696
753
|
assertNoOwnProperties(value, path)
|
|
697
|
-
const projected =
|
|
754
|
+
const projected = state.validateOnly
|
|
755
|
+
? (value as Set<RemoteSubsetWireValue>)
|
|
756
|
+
: new Set<RemoteSubsetWireValue>()
|
|
698
757
|
state.wireValues.set(value, projected)
|
|
699
758
|
let index = 0
|
|
700
759
|
for (const entry of value) {
|
|
701
|
-
|
|
760
|
+
const result = projectWireValue(entry, `${path}.values[${index}]`, state)
|
|
761
|
+
if (!state.validateOnly) projected.add(result)
|
|
702
762
|
index++
|
|
703
763
|
}
|
|
704
764
|
return projected
|
|
@@ -712,7 +772,9 @@ function projectWireRecord(
|
|
|
712
772
|
const source = requirePlainRecord(value, path)
|
|
713
773
|
const existing = state.wireValues.get(source)
|
|
714
774
|
if (existing) return existing as RemoteSubsetWireRecord
|
|
715
|
-
const projected: RemoteSubsetWireRecord =
|
|
775
|
+
const projected: RemoteSubsetWireRecord = state.validateOnly
|
|
776
|
+
? (source as RemoteSubsetWireRecord)
|
|
777
|
+
: {}
|
|
716
778
|
state.wireValues.set(source, projected)
|
|
717
779
|
|
|
718
780
|
for (const key of ownKeys(source, path)) {
|
|
@@ -724,12 +786,15 @@ function projectWireRecord(
|
|
|
724
786
|
if (!descriptor || !descriptor.enumerable || !(`value` in descriptor)) {
|
|
725
787
|
throw new RemoteSubsetWireValueError(childPath, `non-data property`)
|
|
726
788
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
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
|
+
}
|
|
733
798
|
}
|
|
734
799
|
return projected
|
|
735
800
|
}
|