@effect/platform-browser 4.0.0-beta.66 → 4.0.0-beta.68
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/dist/BrowserCrypto.d.ts +23 -0
- package/dist/BrowserCrypto.d.ts.map +1 -0
- package/dist/BrowserCrypto.js +61 -0
- package/dist/BrowserCrypto.js.map +1 -0
- package/dist/BrowserHttpClient.d.ts +23 -13
- package/dist/BrowserHttpClient.d.ts.map +1 -1
- package/dist/BrowserHttpClient.js +49 -12
- package/dist/BrowserHttpClient.js.map +1 -1
- package/dist/BrowserKeyValueStore.d.ts +15 -8
- package/dist/BrowserKeyValueStore.d.ts.map +1 -1
- package/dist/BrowserKeyValueStore.js +128 -4
- package/dist/BrowserKeyValueStore.js.map +1 -1
- package/dist/BrowserPersistence.d.ts +6 -2
- package/dist/BrowserPersistence.d.ts.map +1 -1
- package/dist/BrowserPersistence.js +6 -2
- package/dist/BrowserPersistence.js.map +1 -1
- package/dist/BrowserRuntime.d.ts +31 -4
- package/dist/BrowserRuntime.d.ts.map +1 -1
- package/dist/BrowserRuntime.js +3 -1
- package/dist/BrowserRuntime.js.map +1 -1
- package/dist/BrowserSocket.d.ts +31 -6
- package/dist/BrowserSocket.d.ts.map +1 -1
- package/dist/BrowserSocket.js +31 -6
- package/dist/BrowserSocket.js.map +1 -1
- package/dist/BrowserStream.d.ts +25 -3
- package/dist/BrowserStream.d.ts.map +1 -1
- package/dist/BrowserStream.js +25 -3
- package/dist/BrowserStream.js.map +1 -1
- package/dist/BrowserWorker.d.ts +8 -4
- package/dist/BrowserWorker.d.ts.map +1 -1
- package/dist/BrowserWorker.js +29 -5
- package/dist/BrowserWorker.js.map +1 -1
- package/dist/BrowserWorkerRunner.d.ts +12 -6
- package/dist/BrowserWorkerRunner.d.ts.map +1 -1
- package/dist/BrowserWorkerRunner.js +31 -7
- package/dist/BrowserWorkerRunner.js.map +1 -1
- package/dist/Clipboard.d.ts +35 -11
- package/dist/Clipboard.d.ts.map +1 -1
- package/dist/Clipboard.js +31 -9
- package/dist/Clipboard.js.map +1 -1
- package/dist/Geolocation.d.ts +52 -18
- package/dist/Geolocation.d.ts.map +1 -1
- package/dist/Geolocation.js +44 -14
- package/dist/Geolocation.js.map +1 -1
- package/dist/IndexedDb.d.ts +38 -11
- package/dist/IndexedDb.d.ts.map +1 -1
- package/dist/IndexedDb.js +35 -13
- package/dist/IndexedDb.js.map +1 -1
- package/dist/IndexedDbDatabase.d.ts +57 -10
- package/dist/IndexedDbDatabase.d.ts.map +1 -1
- package/dist/IndexedDbDatabase.js +36 -3
- package/dist/IndexedDbDatabase.js.map +1 -1
- package/dist/IndexedDbQueryBuilder.d.ts +102 -28
- package/dist/IndexedDbQueryBuilder.d.ts.map +1 -1
- package/dist/IndexedDbQueryBuilder.js +56 -26
- package/dist/IndexedDbQueryBuilder.js.map +1 -1
- package/dist/IndexedDbTable.d.ts +57 -13
- package/dist/IndexedDbTable.d.ts.map +1 -1
- package/dist/IndexedDbTable.js +21 -1
- package/dist/IndexedDbTable.js.map +1 -1
- package/dist/IndexedDbVersion.d.ts +37 -7
- package/dist/IndexedDbVersion.d.ts.map +1 -1
- package/dist/IndexedDbVersion.js +3 -1
- package/dist/IndexedDbVersion.js.map +1 -1
- package/dist/Permissions.d.ts +38 -11
- package/dist/Permissions.d.ts.map +1 -1
- package/dist/Permissions.js +33 -8
- package/dist/Permissions.js.map +1 -1
- package/dist/index.d.ts +334 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +334 -11
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/BrowserCrypto.ts +71 -0
- package/src/BrowserHttpClient.ts +53 -14
- package/src/BrowserKeyValueStore.ts +144 -6
- package/src/BrowserPersistence.ts +19 -3
- package/src/BrowserRuntime.ts +31 -4
- package/src/BrowserSocket.ts +31 -6
- package/src/BrowserStream.ts +25 -3
- package/src/BrowserWorker.ts +29 -5
- package/src/BrowserWorkerRunner.ts +31 -7
- package/src/Clipboard.ts +35 -11
- package/src/Geolocation.ts +52 -18
- package/src/IndexedDb.ts +39 -21
- package/src/IndexedDbDatabase.ts +57 -10
- package/src/IndexedDbQueryBuilder.ts +171 -58
- package/src/IndexedDbTable.ts +57 -13
- package/src/IndexedDbVersion.ts +37 -7
- package/src/Permissions.ts +38 -11
- package/src/index.ts +335 -11
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Builds effectful, schema-aware queries for typed browser IndexedDB versions.
|
|
3
|
+
*
|
|
4
|
+
* An `IndexedDbQueryBuilder` is created from an open database and a version's
|
|
5
|
+
* table descriptors, then exposes `from(tableName)` as the entry point for
|
|
6
|
+
* table operations. The resulting query objects can select, count, delete,
|
|
7
|
+
* insert, upsert, clear tables, stream paged reads, react to invalidations, and
|
|
8
|
+
* run multiple effects in a shared `IDBTransaction` with `withTransaction`.
|
|
9
|
+
*
|
|
10
|
+
* Use this module for local browser persistence such as caches, offline-first
|
|
11
|
+
* state, background queues, drafts, and other client-side data where writes
|
|
12
|
+
* should be encoded through `Schema` and reads should be decoded before they
|
|
13
|
+
* reach application code.
|
|
14
|
+
*
|
|
15
|
+
* Index and range helpers are thinly typed wrappers around IndexedDB object
|
|
16
|
+
* stores, indexes, `IDBKeyRange`, and cursors. Index names must be declared on
|
|
17
|
+
* the table and created during migrations; without an index, queries use the
|
|
18
|
+
* object store key path. Range values are encoded IndexedDB key values, and
|
|
19
|
+
* compound key paths must follow the declared key order. Filters, offsets,
|
|
20
|
+
* reverse reads, out-of-line keys, and limited deletes require cursor-based
|
|
21
|
+
* scans, while simpler selects can use `getAll`.
|
|
22
|
+
*
|
|
23
|
+
* Table schema details affect runtime behavior: auto-increment writes may omit
|
|
24
|
+
* the generated numeric key, stores without a key path require an out-of-line
|
|
25
|
+
* `key` for writes and add that `key` back to selected rows, and schema
|
|
26
|
+
* mismatches surface as `EncodeError` or `DecodeError` query failures.
|
|
27
|
+
*
|
|
2
28
|
* @since 4.0.0
|
|
3
29
|
*/
|
|
4
30
|
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
31
|
+
import * as Cause from "effect/Cause"
|
|
5
32
|
import * as Context from "effect/Context"
|
|
6
33
|
import * as Data from "effect/Data"
|
|
7
34
|
import * as Effect from "effect/Effect"
|
|
@@ -43,19 +70,22 @@ const CommonProto = {
|
|
|
43
70
|
}
|
|
44
71
|
|
|
45
72
|
/**
|
|
46
|
-
*
|
|
73
|
+
* String union describing IndexedDB query failure categories such as decoding, encoding, and transaction errors.
|
|
74
|
+
*
|
|
47
75
|
* @category errors
|
|
76
|
+
* @since 4.0.0
|
|
48
77
|
*/
|
|
49
78
|
export type ErrorReason =
|
|
50
|
-
| "NotFoundError"
|
|
51
79
|
| "UnknownError"
|
|
52
80
|
| "DecodeError"
|
|
53
81
|
| "EncodeError"
|
|
54
82
|
| "TransactionError"
|
|
55
83
|
|
|
56
84
|
/**
|
|
57
|
-
*
|
|
85
|
+
* Tagged error for IndexedDB query operations, carrying a query error reason and the original cause.
|
|
86
|
+
*
|
|
58
87
|
* @category errors
|
|
88
|
+
* @since 4.0.0
|
|
59
89
|
*/
|
|
60
90
|
export class IndexedDbQueryError extends Data.TaggedError(
|
|
61
91
|
"IndexedDbQueryError"
|
|
@@ -64,6 +94,8 @@ export class IndexedDbQueryError extends Data.TaggedError(
|
|
|
64
94
|
cause: unknown
|
|
65
95
|
}> {
|
|
66
96
|
/**
|
|
97
|
+
* Marks this value as an IndexedDB query builder error for runtime guards.
|
|
98
|
+
*
|
|
67
99
|
* @since 4.0.0
|
|
68
100
|
*/
|
|
69
101
|
readonly [ErrorTypeId]: typeof ErrorTypeId = ErrorTypeId
|
|
@@ -72,8 +104,10 @@ export class IndexedDbQueryError extends Data.TaggedError(
|
|
|
72
104
|
}
|
|
73
105
|
|
|
74
106
|
/**
|
|
75
|
-
*
|
|
107
|
+
* Typed query builder for an IndexedDB version, with helpers for table queries, database access, clearing data, and running effects in a shared transaction.
|
|
108
|
+
*
|
|
76
109
|
* @category models
|
|
110
|
+
* @since 4.0.0
|
|
77
111
|
*/
|
|
78
112
|
export interface IndexedDbQueryBuilder<
|
|
79
113
|
Source extends IndexedDbVersion.AnyWithProps
|
|
@@ -96,6 +130,9 @@ export interface IndexedDbQueryBuilder<
|
|
|
96
130
|
table: Name
|
|
97
131
|
) => IndexedDbQuery.From<IndexedDbVersion.TableWithName<Source, Name>>
|
|
98
132
|
|
|
133
|
+
/** @internal */
|
|
134
|
+
readonly fromCache: Map<string, IndexedDbQuery.From<IndexedDbVersion.TableWithName<Source, any>>>
|
|
135
|
+
|
|
99
136
|
readonly clearAll: Effect.Effect<void, IndexedDbQueryError>
|
|
100
137
|
|
|
101
138
|
readonly withTransaction: <
|
|
@@ -111,29 +148,36 @@ export interface IndexedDbQueryBuilder<
|
|
|
111
148
|
}
|
|
112
149
|
|
|
113
150
|
/**
|
|
114
|
-
*
|
|
151
|
+
* Valid key-path type for a table schema, using encoded fields whose values are IndexedDB-valid keys.
|
|
152
|
+
*
|
|
115
153
|
* @category models
|
|
154
|
+
* @since 4.0.0
|
|
116
155
|
*/
|
|
117
156
|
export type KeyPath<TableSchema extends IndexedDbTable.AnySchemaStruct> =
|
|
118
157
|
| IndexedDbValidKeys<TableSchema>
|
|
119
158
|
| NonEmptyReadonlyArray<IndexedDbValidKeys<TableSchema>>
|
|
120
159
|
|
|
121
160
|
/**
|
|
122
|
-
*
|
|
161
|
+
* Valid numeric key-path type for a table schema, used for auto-increment key paths.
|
|
162
|
+
*
|
|
123
163
|
* @category models
|
|
164
|
+
* @since 4.0.0
|
|
124
165
|
*/
|
|
125
166
|
export type KeyPathNumber<TableSchema extends IndexedDbTable.AnySchemaStruct> =
|
|
126
167
|
| IndexedDbValidNumberKeys<TableSchema>
|
|
127
168
|
| NonEmptyReadonlyArray<IndexedDbValidNumberKeys<TableSchema>>
|
|
128
169
|
|
|
129
170
|
/**
|
|
171
|
+
* Namespace containing the typed IndexedDB query model interfaces and helper types.
|
|
172
|
+
*
|
|
130
173
|
* @since 4.0.0
|
|
131
|
-
* @category models
|
|
132
174
|
*/
|
|
133
175
|
export declare namespace IndexedDbQuery {
|
|
134
176
|
/**
|
|
135
|
-
*
|
|
177
|
+
* Decoded row type returned by select queries, adding a `key` field when the table does not define a key path.
|
|
178
|
+
*
|
|
136
179
|
* @category models
|
|
180
|
+
* @since 4.0.0
|
|
137
181
|
*/
|
|
138
182
|
export type SelectType<
|
|
139
183
|
Table extends IndexedDbTable.AnyWithProps
|
|
@@ -143,8 +187,10 @@ export declare namespace IndexedDbQuery {
|
|
|
143
187
|
IndexedDbTable.TableSchema<Table>["Type"]
|
|
144
188
|
|
|
145
189
|
/**
|
|
146
|
-
*
|
|
190
|
+
* Input type for insert and upsert operations, adjusted for auto-increment keys and out-of-line keys.
|
|
191
|
+
*
|
|
147
192
|
* @category models
|
|
193
|
+
* @since 4.0.0
|
|
148
194
|
*/
|
|
149
195
|
export type ModifyType<
|
|
150
196
|
Table extends IndexedDbTable.AnyWithProps
|
|
@@ -175,8 +221,10 @@ export declare namespace IndexedDbQuery {
|
|
|
175
221
|
: {})
|
|
176
222
|
|
|
177
223
|
/**
|
|
178
|
-
*
|
|
224
|
+
* Value type accepted by `equals` comparisons for a table key path or index.
|
|
225
|
+
*
|
|
179
226
|
* @category models
|
|
227
|
+
* @since 4.0.0
|
|
180
228
|
*/
|
|
181
229
|
export type EqualsType<
|
|
182
230
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -187,8 +235,10 @@ export declare namespace IndexedDbQuery {
|
|
|
187
235
|
: { [I in keyof KeyPath]: KeyPath[I] extends keyof Type ? Type[KeyPath[I]] | [] : never }
|
|
188
236
|
|
|
189
237
|
/**
|
|
190
|
-
*
|
|
238
|
+
* Value type accepted by range comparisons for a table key path or index, including partial tuples for compound indexes.
|
|
239
|
+
*
|
|
191
240
|
* @category models
|
|
241
|
+
* @since 4.0.0
|
|
192
242
|
*/
|
|
193
243
|
export type ExtractIndexType<
|
|
194
244
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -204,14 +254,18 @@ export declare namespace IndexedDbQuery {
|
|
|
204
254
|
never
|
|
205
255
|
|
|
206
256
|
/**
|
|
207
|
-
*
|
|
257
|
+
* Mutation input type for insert and upsert operations, including any required key fields.
|
|
258
|
+
*
|
|
208
259
|
* @category models
|
|
260
|
+
* @since 4.0.0
|
|
209
261
|
*/
|
|
210
262
|
export type ModifyWithKey<Table extends IndexedDbTable.AnyWithProps> = ModifyType<Table>
|
|
211
263
|
|
|
212
264
|
/**
|
|
213
|
-
*
|
|
265
|
+
* Query entry point for a table, exposing clear, select, count, delete, insert, and upsert operations.
|
|
266
|
+
*
|
|
214
267
|
* @category models
|
|
268
|
+
* @since 4.0.0
|
|
215
269
|
*/
|
|
216
270
|
export interface From<Table extends IndexedDbTable.AnyWithProps> {
|
|
217
271
|
readonly table: Table
|
|
@@ -228,6 +282,12 @@ export declare namespace IndexedDbQuery {
|
|
|
228
282
|
(): Select<Table, never>
|
|
229
283
|
}
|
|
230
284
|
|
|
285
|
+
/** @internal */
|
|
286
|
+
readonly selectCache: Map<
|
|
287
|
+
string | undefined,
|
|
288
|
+
IndexedDbQuery.Select<any, never>
|
|
289
|
+
>
|
|
290
|
+
|
|
231
291
|
readonly count: {
|
|
232
292
|
<Index extends IndexedDbDatabase.IndexFromTable<Table>>(
|
|
233
293
|
index: Index
|
|
@@ -235,6 +295,12 @@ export declare namespace IndexedDbQuery {
|
|
|
235
295
|
(): Count<Table, never>
|
|
236
296
|
}
|
|
237
297
|
|
|
298
|
+
/** @internal */
|
|
299
|
+
readonly countCache: Map<
|
|
300
|
+
string | undefined,
|
|
301
|
+
IndexedDbQuery.Count<any, never>
|
|
302
|
+
>
|
|
303
|
+
|
|
238
304
|
readonly delete: {
|
|
239
305
|
<Index extends IndexedDbDatabase.IndexFromTable<Table>>(
|
|
240
306
|
index: Index
|
|
@@ -242,6 +308,12 @@ export declare namespace IndexedDbQuery {
|
|
|
242
308
|
(): DeletePartial<Table, never>
|
|
243
309
|
}
|
|
244
310
|
|
|
311
|
+
/** @internal */
|
|
312
|
+
readonly deleteCache: Map<
|
|
313
|
+
string | undefined,
|
|
314
|
+
IndexedDbQuery.DeletePartial<any, never>
|
|
315
|
+
>
|
|
316
|
+
|
|
245
317
|
readonly insert: (value: ModifyWithKey<Table>) => Modify<Table>
|
|
246
318
|
readonly insertAll: (
|
|
247
319
|
values: Array<ModifyWithKey<Table>>
|
|
@@ -253,8 +325,10 @@ export declare namespace IndexedDbQuery {
|
|
|
253
325
|
}
|
|
254
326
|
|
|
255
327
|
/**
|
|
256
|
-
*
|
|
328
|
+
* Effect model for clearing all rows from a table.
|
|
329
|
+
*
|
|
257
330
|
* @category models
|
|
331
|
+
* @since 4.0.0
|
|
258
332
|
*/
|
|
259
333
|
export interface Clear<
|
|
260
334
|
Table extends IndexedDbTable.AnyWithProps
|
|
@@ -265,8 +339,10 @@ export declare namespace IndexedDbQuery {
|
|
|
265
339
|
type ComparisonKeys = "equals" | "gte" | "lte" | "gt" | "lt" | "between"
|
|
266
340
|
|
|
267
341
|
/**
|
|
268
|
-
*
|
|
342
|
+
* Effect model for counting table rows, optionally constrained by an index and key-range comparisons.
|
|
343
|
+
*
|
|
269
344
|
* @category models
|
|
345
|
+
* @since 4.0.0
|
|
270
346
|
*/
|
|
271
347
|
export interface Count<
|
|
272
348
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -308,8 +384,10 @@ export declare namespace IndexedDbQuery {
|
|
|
308
384
|
}
|
|
309
385
|
|
|
310
386
|
/**
|
|
311
|
-
*
|
|
387
|
+
* Intermediate delete builder used to choose a key range or limit before producing an executable delete query.
|
|
388
|
+
*
|
|
312
389
|
* @category models
|
|
390
|
+
* @since 4.0.0
|
|
313
391
|
*/
|
|
314
392
|
export interface DeletePartial<
|
|
315
393
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -356,8 +434,10 @@ export declare namespace IndexedDbQuery {
|
|
|
356
434
|
> = Omit<Delete<Table, Index, ExcludedKeys>, ExcludedKeys>
|
|
357
435
|
|
|
358
436
|
/**
|
|
359
|
-
*
|
|
437
|
+
* Effect model for deleting rows from a table, with optional key-range, limit, filter, and reactivity invalidation helpers.
|
|
438
|
+
*
|
|
360
439
|
* @category models
|
|
440
|
+
* @since 4.0.0
|
|
361
441
|
*/
|
|
362
442
|
export interface Delete<
|
|
363
443
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -399,8 +479,10 @@ export declare namespace IndexedDbQuery {
|
|
|
399
479
|
> = Omit<Select<Table, Index, ExcludedKeys>, ExcludedKeys>
|
|
400
480
|
|
|
401
481
|
/**
|
|
402
|
-
*
|
|
482
|
+
* Effect model for selecting rows from a table, with chainable range, paging, filtering, streaming, and reactive query helpers.
|
|
483
|
+
*
|
|
403
484
|
* @category models
|
|
485
|
+
* @since 4.0.0
|
|
404
486
|
*/
|
|
405
487
|
export interface Select<
|
|
406
488
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -502,8 +584,10 @@ export declare namespace IndexedDbQuery {
|
|
|
502
584
|
}
|
|
503
585
|
|
|
504
586
|
/**
|
|
505
|
-
*
|
|
587
|
+
* Effect model for selecting the first matching row, failing with `NoSuchElementError` when no row is found.
|
|
588
|
+
*
|
|
506
589
|
* @category models
|
|
590
|
+
* @since 4.0.0
|
|
507
591
|
*/
|
|
508
592
|
export interface First<
|
|
509
593
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -511,7 +595,7 @@ export declare namespace IndexedDbQuery {
|
|
|
511
595
|
> extends
|
|
512
596
|
Effect.Effect<
|
|
513
597
|
SelectType<Table>,
|
|
514
|
-
IndexedDbQueryError,
|
|
598
|
+
IndexedDbQueryError | Cause.NoSuchElementError,
|
|
515
599
|
IndexedDbTable.Context<Table>
|
|
516
600
|
>
|
|
517
601
|
{
|
|
@@ -526,7 +610,7 @@ export declare namespace IndexedDbQuery {
|
|
|
526
610
|
keys?: ReadonlyArray<unknown> | Record.ReadonlyRecord<string, ReadonlyArray<unknown>> | undefined
|
|
527
611
|
) => Stream.Stream<
|
|
528
612
|
SelectType<Table>,
|
|
529
|
-
IndexedDbQueryError,
|
|
613
|
+
IndexedDbQueryError | Cause.NoSuchElementError,
|
|
530
614
|
IndexedDbTable.Context<Table>
|
|
531
615
|
>
|
|
532
616
|
|
|
@@ -538,15 +622,17 @@ export declare namespace IndexedDbQuery {
|
|
|
538
622
|
readonly reactiveQueue: (
|
|
539
623
|
keys: ReadonlyArray<unknown> | Record.ReadonlyRecord<string, ReadonlyArray<unknown>>
|
|
540
624
|
) => Effect.Effect<
|
|
541
|
-
Queue.Dequeue<SelectType<Table>, IndexedDbQueryError>,
|
|
625
|
+
Queue.Dequeue<SelectType<Table>, IndexedDbQueryError | Cause.NoSuchElementError>,
|
|
542
626
|
never,
|
|
543
627
|
Scope.Scope | IndexedDbTable.Context<Table>
|
|
544
628
|
>
|
|
545
629
|
}
|
|
546
630
|
|
|
547
631
|
/**
|
|
548
|
-
*
|
|
632
|
+
* Effect model for a select query filtered by one or more predicates over encoded table rows.
|
|
633
|
+
*
|
|
549
634
|
* @category models
|
|
635
|
+
* @since 4.0.0
|
|
550
636
|
*/
|
|
551
637
|
export interface Filter<
|
|
552
638
|
Table extends IndexedDbTable.AnyWithProps,
|
|
@@ -566,8 +652,10 @@ export declare namespace IndexedDbQuery {
|
|
|
566
652
|
}
|
|
567
653
|
|
|
568
654
|
/**
|
|
569
|
-
*
|
|
655
|
+
* Effect model for inserting or upserting one row, returning the resulting IndexedDB key and supporting reactivity invalidation.
|
|
656
|
+
*
|
|
570
657
|
* @category models
|
|
658
|
+
* @since 4.0.0
|
|
571
659
|
*/
|
|
572
660
|
export interface Modify<
|
|
573
661
|
Table extends IndexedDbTable.AnyWithProps
|
|
@@ -593,8 +681,10 @@ export declare namespace IndexedDbQuery {
|
|
|
593
681
|
}
|
|
594
682
|
|
|
595
683
|
/**
|
|
596
|
-
*
|
|
684
|
+
* Effect model for inserting or upserting multiple rows, returning the resulting IndexedDB keys and supporting reactivity invalidation.
|
|
685
|
+
*
|
|
597
686
|
* @category models
|
|
687
|
+
* @since 4.0.0
|
|
598
688
|
*/
|
|
599
689
|
export interface ModifyAll<
|
|
600
690
|
Table extends IndexedDbTable.AnyWithProps
|
|
@@ -621,8 +711,10 @@ export declare namespace IndexedDbQuery {
|
|
|
621
711
|
}
|
|
622
712
|
|
|
623
713
|
/**
|
|
624
|
-
*
|
|
714
|
+
* Service tag for the active `IDBTransaction` used to share a transaction across IndexedDB query effects.
|
|
715
|
+
*
|
|
625
716
|
* @category models
|
|
717
|
+
* @since 4.0.0
|
|
626
718
|
*/
|
|
627
719
|
export class IndexedDbTransaction extends Context.Service<IndexedDbTransaction, globalThis.IDBTransaction>()(
|
|
628
720
|
"@effect/platform-browser/IndexedDbQueryBuilder/IndexedDbTransaction"
|
|
@@ -885,7 +977,7 @@ const applyFirst = Effect.fnUntraced(function*(
|
|
|
885
977
|
) {
|
|
886
978
|
const keyPath = query.select.from.table.keyPath
|
|
887
979
|
|
|
888
|
-
const data = yield* Effect.callback<any, IndexedDbQueryError>((resume) => {
|
|
980
|
+
const data = yield* Effect.callback<any, IndexedDbQueryError | Cause.NoSuchElementError>((resume) => {
|
|
889
981
|
const { keyRange, store } = getReadonlyObjectStore(query.select)
|
|
890
982
|
|
|
891
983
|
if (keyRange !== undefined) {
|
|
@@ -925,12 +1017,7 @@ const applyFirst = Effect.fnUntraced(function*(
|
|
|
925
1017
|
|
|
926
1018
|
if (value === undefined) {
|
|
927
1019
|
resume(
|
|
928
|
-
Effect.fail(
|
|
929
|
-
new IndexedDbQueryError({
|
|
930
|
-
reason: "NotFoundError",
|
|
931
|
-
cause: request.error
|
|
932
|
-
})
|
|
933
|
-
)
|
|
1020
|
+
Effect.fail(new Cause.NoSuchElementError(`No such element in table ${query.select.from.table.tableName}`))
|
|
934
1021
|
)
|
|
935
1022
|
} else {
|
|
936
1023
|
resume(
|
|
@@ -964,15 +1051,11 @@ const applyModify = Effect.fnUntraced(function*({
|
|
|
964
1051
|
const autoIncrement = query.from.table.autoIncrement as boolean
|
|
965
1052
|
const keyPath = query.from.table.keyPath
|
|
966
1053
|
const table = query.from.table
|
|
967
|
-
const schema = autoIncrement && value[keyPath] === undefined
|
|
1054
|
+
const schema: Schema.Top = autoIncrement && value[keyPath] === undefined
|
|
968
1055
|
? table.autoincrementSchema
|
|
969
1056
|
: table.tableSchema
|
|
970
1057
|
|
|
971
|
-
const encodedValue = yield*
|
|
972
|
-
autoIncrement && value[keyPath] === undefined
|
|
973
|
-
? table.autoincrementSchema
|
|
974
|
-
: table.tableSchema
|
|
975
|
-
)(value).pipe(
|
|
1058
|
+
const encodedValue = yield* schema.makeEffect(value).pipe(
|
|
976
1059
|
Effect.flatMap(Schema.encodeUnknownEffect(schema)),
|
|
977
1060
|
Effect.mapError(
|
|
978
1061
|
(error) =>
|
|
@@ -1229,34 +1312,52 @@ const FromProto: Omit<
|
|
|
1229
1312
|
| "IDBKeyRange"
|
|
1230
1313
|
| "transaction"
|
|
1231
1314
|
| "reactivity"
|
|
1315
|
+
| "selectCache"
|
|
1316
|
+
| "countCache"
|
|
1317
|
+
| "deleteCache"
|
|
1232
1318
|
> = {
|
|
1233
1319
|
...CommonProto,
|
|
1234
1320
|
select<Index extends IndexedDbDatabase.IndexFromTable<any>>(
|
|
1235
1321
|
this: IndexedDbQuery.From<any>,
|
|
1236
1322
|
index?: Index
|
|
1237
1323
|
) {
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1324
|
+
let select = this.selectCache.get(index)
|
|
1325
|
+
if (select === undefined) {
|
|
1326
|
+
select = makeSelect({
|
|
1327
|
+
from: this,
|
|
1328
|
+
index
|
|
1329
|
+
})
|
|
1330
|
+
this.selectCache.set(index, select)
|
|
1331
|
+
}
|
|
1332
|
+
return select
|
|
1242
1333
|
},
|
|
1243
1334
|
count<Index extends IndexedDbDatabase.IndexFromTable<any>>(
|
|
1244
1335
|
this: IndexedDbQuery.From<any>,
|
|
1245
1336
|
index?: Index
|
|
1246
1337
|
) {
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1338
|
+
let count = this.countCache.get(index)
|
|
1339
|
+
if (count === undefined) {
|
|
1340
|
+
count = makeCount({
|
|
1341
|
+
from: this,
|
|
1342
|
+
index
|
|
1343
|
+
})
|
|
1344
|
+
this.countCache.set(index, count)
|
|
1345
|
+
}
|
|
1346
|
+
return count
|
|
1251
1347
|
},
|
|
1252
1348
|
delete<Index extends IndexedDbDatabase.IndexFromTable<any>>(
|
|
1253
1349
|
this: IndexedDbQuery.From<any>,
|
|
1254
1350
|
index?: Index
|
|
1255
1351
|
) {
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1352
|
+
let cached = this.deleteCache.get(index)
|
|
1353
|
+
if (cached === undefined) {
|
|
1354
|
+
cached = makeDeletePartial({
|
|
1355
|
+
from: this,
|
|
1356
|
+
index
|
|
1357
|
+
})
|
|
1358
|
+
this.deleteCache.set(index, cached)
|
|
1359
|
+
}
|
|
1360
|
+
return cached
|
|
1260
1361
|
},
|
|
1261
1362
|
insert(this: IndexedDbQuery.From<any>, value: any) {
|
|
1262
1363
|
return makeModify({ from: this, value, operation: "add" })
|
|
@@ -1292,6 +1393,9 @@ const makeFrom = <
|
|
|
1292
1393
|
self.database = options.database
|
|
1293
1394
|
self.IDBKeyRange = options.IDBKeyRange
|
|
1294
1395
|
self.reactivity = options.reactivity
|
|
1396
|
+
self.selectCache = new Map()
|
|
1397
|
+
self.countCache = new Map()
|
|
1398
|
+
self.deleteCache = new Map()
|
|
1295
1399
|
return self
|
|
1296
1400
|
}
|
|
1297
1401
|
|
|
@@ -1825,6 +1929,7 @@ const makeModifyAll = <
|
|
|
1825
1929
|
|
|
1826
1930
|
const QueryBuilderProto: Omit<
|
|
1827
1931
|
IndexedDbQueryBuilder<any>,
|
|
1932
|
+
| "fromCache"
|
|
1828
1933
|
| "tables"
|
|
1829
1934
|
| "database"
|
|
1830
1935
|
| "IDBKeyRange"
|
|
@@ -1843,12 +1948,17 @@ const QueryBuilderProto: Omit<
|
|
|
1843
1948
|
})
|
|
1844
1949
|
},
|
|
1845
1950
|
from(this: IndexedDbQueryBuilder<any>, table: any) {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1951
|
+
let cached = this.fromCache.get(table)
|
|
1952
|
+
if (cached === undefined) {
|
|
1953
|
+
cached = makeFrom({
|
|
1954
|
+
database: this.database,
|
|
1955
|
+
IDBKeyRange: this.IDBKeyRange,
|
|
1956
|
+
table: this.tables.get(table)!,
|
|
1957
|
+
reactivity: this.reactivity
|
|
1958
|
+
})
|
|
1959
|
+
this.fromCache.set(table, cached)
|
|
1960
|
+
}
|
|
1961
|
+
return cached as any
|
|
1852
1962
|
},
|
|
1853
1963
|
get clearAll() {
|
|
1854
1964
|
const self = this as IndexedDbQueryBuilder<any>
|
|
@@ -1871,8 +1981,10 @@ const QueryBuilderProto: Omit<
|
|
|
1871
1981
|
}
|
|
1872
1982
|
|
|
1873
1983
|
/**
|
|
1874
|
-
*
|
|
1984
|
+
* Creates an `IndexedDbQueryBuilder` from an open database reference, key-range constructor, table map, and reactivity service.
|
|
1985
|
+
*
|
|
1875
1986
|
* @category constructors
|
|
1987
|
+
* @since 4.0.0
|
|
1876
1988
|
*/
|
|
1877
1989
|
export const make = <Source extends IndexedDbVersion.AnyWithProps>({
|
|
1878
1990
|
IDBKeyRange,
|
|
@@ -1890,6 +2002,7 @@ export const make = <Source extends IndexedDbVersion.AnyWithProps>({
|
|
|
1890
2002
|
self.database = database
|
|
1891
2003
|
self.reactivity = reactivity
|
|
1892
2004
|
self.IDBKeyRange = IDBKeyRange
|
|
2005
|
+
self.fromCache = new Map()
|
|
1893
2006
|
return self
|
|
1894
2007
|
}
|
|
1895
2008
|
|
package/src/IndexedDbTable.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Defines typed table descriptors for the browser IndexedDB integration.
|
|
3
|
+
*
|
|
4
|
+
* An `IndexedDbTable` records the object store name, row schema, primary key
|
|
5
|
+
* path, indexes, auto-increment behavior, and transaction durability used by
|
|
6
|
+
* database versions, migrations, and typed queries. These descriptors are
|
|
7
|
+
* useful for local caches, offline-first application state, background queues,
|
|
8
|
+
* drafts, and other browser-persisted data that should be validated through
|
|
9
|
+
* `Schema`.
|
|
10
|
+
*
|
|
11
|
+
* Key paths and index paths must reference encoded schema fields whose values
|
|
12
|
+
* are valid IndexedDB keys, and compound paths are represented as readonly
|
|
13
|
+
* arrays. Tables without a key path use an out-of-line `key` that is added to
|
|
14
|
+
* reads and required for writes, so the row schema itself cannot define a
|
|
15
|
+
* `key` field. Auto-increment tables require a numeric key path; when that key
|
|
16
|
+
* is omitted on write, the module uses a derived schema without the generated
|
|
17
|
+
* key. Declaring indexes here types query builder index selection, but the
|
|
18
|
+
* indexes still need to be created during database migrations.
|
|
19
|
+
*
|
|
2
20
|
* @since 4.0.0
|
|
3
21
|
*/
|
|
4
22
|
import { type Pipeable, pipeArguments } from "effect/Pipeable"
|
|
@@ -11,8 +29,10 @@ import type * as IndexedDbQueryBuilder from "./IndexedDbQueryBuilder.ts"
|
|
|
11
29
|
const TypeId = "~@effect/platform-browser/IndexedDbTable"
|
|
12
30
|
|
|
13
31
|
/**
|
|
14
|
-
*
|
|
32
|
+
* Typed IndexedDB table definition containing its name, schema, key path, indexes, auto-increment setting, and transaction durability.
|
|
33
|
+
*
|
|
15
34
|
* @category interface
|
|
35
|
+
* @since 4.0.0
|
|
16
36
|
*/
|
|
17
37
|
export interface IndexedDbTable<
|
|
18
38
|
out Name extends string,
|
|
@@ -38,16 +58,20 @@ export interface IndexedDbTable<
|
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
/**
|
|
41
|
-
*
|
|
61
|
+
* Schema constraint for table schemas that expose struct fields.
|
|
62
|
+
*
|
|
42
63
|
* @category models
|
|
64
|
+
* @since 4.0.0
|
|
43
65
|
*/
|
|
44
66
|
export type AnySchemaStruct = Schema.Top & {
|
|
45
67
|
readonly fields: Schema.Struct.Fields
|
|
46
68
|
}
|
|
47
69
|
|
|
48
70
|
/**
|
|
49
|
-
*
|
|
71
|
+
* Type-erased shape of an `IndexedDbTable` used when table type parameters are not needed.
|
|
72
|
+
*
|
|
50
73
|
* @category models
|
|
74
|
+
* @since 4.0.0
|
|
51
75
|
*/
|
|
52
76
|
export interface Any {
|
|
53
77
|
readonly [TypeId]: typeof TypeId
|
|
@@ -62,8 +86,10 @@ export interface Any {
|
|
|
62
86
|
}
|
|
63
87
|
|
|
64
88
|
/**
|
|
65
|
-
*
|
|
89
|
+
* Type-erased `IndexedDbTable` retaining the table interface properties with broad type parameters.
|
|
90
|
+
*
|
|
66
91
|
* @category models
|
|
92
|
+
* @since 4.0.0
|
|
67
93
|
*/
|
|
68
94
|
export type AnyWithProps = IndexedDbTable<
|
|
69
95
|
string,
|
|
@@ -74,50 +100,66 @@ export type AnyWithProps = IndexedDbTable<
|
|
|
74
100
|
>
|
|
75
101
|
|
|
76
102
|
/**
|
|
77
|
-
*
|
|
103
|
+
* Extracts the table name type from an `IndexedDbTable`.
|
|
104
|
+
*
|
|
78
105
|
* @category models
|
|
106
|
+
* @since 4.0.0
|
|
79
107
|
*/
|
|
80
108
|
export type TableName<Table extends Any> = Table["tableName"]
|
|
81
109
|
/**
|
|
82
|
-
*
|
|
110
|
+
* Extracts the key-path type from an `IndexedDbTable`.
|
|
111
|
+
*
|
|
83
112
|
* @category models
|
|
113
|
+
* @since 4.0.0
|
|
84
114
|
*/
|
|
85
115
|
export type KeyPath<Table extends Any> = Table["keyPath"]
|
|
86
116
|
|
|
87
117
|
/**
|
|
88
|
-
*
|
|
118
|
+
* Extracts the auto-increment flag type from an `IndexedDbTable`.
|
|
119
|
+
*
|
|
89
120
|
* @category models
|
|
121
|
+
* @since 4.0.0
|
|
90
122
|
*/
|
|
91
123
|
export type AutoIncrement<Table extends Any> = Table["autoIncrement"]
|
|
92
124
|
|
|
93
125
|
/**
|
|
94
|
-
*
|
|
126
|
+
* Extracts the schema type from an `IndexedDbTable`.
|
|
127
|
+
*
|
|
95
128
|
* @category models
|
|
129
|
+
* @since 4.0.0
|
|
96
130
|
*/
|
|
97
131
|
export type TableSchema<Table extends Any> = Table["tableSchema"]
|
|
98
132
|
/**
|
|
99
|
-
*
|
|
133
|
+
* Extracts the decoding or encoding service requirements needed by an `IndexedDbTable` schema.
|
|
134
|
+
*
|
|
100
135
|
* @category models
|
|
136
|
+
* @since 4.0.0
|
|
101
137
|
*/
|
|
102
138
|
export type Context<Table extends Any> =
|
|
103
139
|
| Table["tableSchema"]["DecodingServices"]
|
|
104
140
|
| Table["tableSchema"]["EncodingServices"]
|
|
105
141
|
|
|
106
142
|
/**
|
|
107
|
-
*
|
|
143
|
+
* Extracts the encoded row type from an `IndexedDbTable` schema.
|
|
144
|
+
*
|
|
108
145
|
* @category models
|
|
146
|
+
* @since 4.0.0
|
|
109
147
|
*/
|
|
110
148
|
export type Encoded<Table extends Any> = Table["tableSchema"]["Encoded"]
|
|
111
149
|
|
|
112
150
|
/**
|
|
113
|
-
*
|
|
151
|
+
* Extracts the index definition map from an `IndexedDbTable`.
|
|
152
|
+
*
|
|
114
153
|
* @category models
|
|
154
|
+
* @since 4.0.0
|
|
115
155
|
*/
|
|
116
156
|
export type Indexes<Table extends Any> = Table["indexes"]
|
|
117
157
|
|
|
118
158
|
/**
|
|
119
|
-
*
|
|
159
|
+
* Selects the table with the given name from a union of `IndexedDbTable` types.
|
|
160
|
+
*
|
|
120
161
|
* @category models
|
|
162
|
+
* @since 4.0.0
|
|
121
163
|
*/
|
|
122
164
|
export type WithName<Table extends Any, TableName extends string> = Extract<
|
|
123
165
|
Table,
|
|
@@ -132,8 +174,10 @@ const Proto = {
|
|
|
132
174
|
}
|
|
133
175
|
|
|
134
176
|
/**
|
|
135
|
-
*
|
|
177
|
+
* Creates a typed IndexedDB table definition from its name, schema, optional key path, indexes, auto-increment flag, and durability.
|
|
178
|
+
*
|
|
136
179
|
* @category constructors
|
|
180
|
+
* @since 4.0.0
|
|
137
181
|
*/
|
|
138
182
|
export const make = <
|
|
139
183
|
const Name extends string,
|