@effect/platform-browser 4.0.0-beta.42 → 4.0.0-beta.44

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.
Files changed (54) hide show
  1. package/dist/BrowserHttpClient.d.ts +3 -3
  2. package/dist/BrowserHttpClient.d.ts.map +1 -1
  3. package/dist/BrowserHttpClient.js +5 -5
  4. package/dist/BrowserHttpClient.js.map +1 -1
  5. package/dist/BrowserWorkerRunner.js +1 -1
  6. package/dist/BrowserWorkerRunner.js.map +1 -1
  7. package/dist/Clipboard.d.ts +5 -2
  8. package/dist/Clipboard.d.ts.map +1 -1
  9. package/dist/Clipboard.js +2 -2
  10. package/dist/Clipboard.js.map +1 -1
  11. package/dist/Geolocation.d.ts +2 -2
  12. package/dist/Geolocation.d.ts.map +1 -1
  13. package/dist/Geolocation.js +2 -2
  14. package/dist/Geolocation.js.map +1 -1
  15. package/dist/IndexedDb.d.ts +50 -0
  16. package/dist/IndexedDb.d.ts.map +1 -0
  17. package/dist/IndexedDb.js +65 -0
  18. package/dist/IndexedDb.js.map +1 -0
  19. package/dist/IndexedDbDatabase.d.ts +105 -0
  20. package/dist/IndexedDbDatabase.d.ts.map +1 -0
  21. package/dist/IndexedDbDatabase.js +321 -0
  22. package/dist/IndexedDbDatabase.js.map +1 -0
  23. package/dist/IndexedDbQueryBuilder.d.ts +342 -0
  24. package/dist/IndexedDbQueryBuilder.d.ts.map +1 -0
  25. package/dist/IndexedDbQueryBuilder.js +869 -0
  26. package/dist/IndexedDbQueryBuilder.js.map +1 -0
  27. package/dist/IndexedDbTable.d.ts +109 -0
  28. package/dist/IndexedDbTable.d.ts.map +1 -0
  29. package/dist/IndexedDbTable.js +38 -0
  30. package/dist/IndexedDbTable.js.map +1 -0
  31. package/dist/IndexedDbVersion.d.ts +50 -0
  32. package/dist/IndexedDbVersion.d.ts.map +1 -0
  33. package/dist/IndexedDbVersion.js +23 -0
  34. package/dist/IndexedDbVersion.js.map +1 -0
  35. package/dist/Permissions.d.ts +5 -2
  36. package/dist/Permissions.d.ts.map +1 -1
  37. package/dist/Permissions.js +2 -2
  38. package/dist/Permissions.js.map +1 -1
  39. package/dist/index.d.ts +20 -0
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +20 -0
  42. package/dist/index.js.map +1 -1
  43. package/package.json +4 -3
  44. package/src/BrowserHttpClient.ts +6 -6
  45. package/src/BrowserWorkerRunner.ts +1 -1
  46. package/src/Clipboard.ts +2 -2
  47. package/src/Geolocation.ts +2 -2
  48. package/src/IndexedDb.ts +97 -0
  49. package/src/IndexedDbDatabase.ts +631 -0
  50. package/src/IndexedDbQueryBuilder.ts +1890 -0
  51. package/src/IndexedDbTable.ts +203 -0
  52. package/src/IndexedDbVersion.ts +89 -0
  53. package/src/Permissions.ts +2 -2
  54. package/src/index.ts +25 -0
@@ -0,0 +1,869 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Data from "effect/Data";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Fiber from "effect/Fiber";
5
+ import { BaseProto } from "effect/Inspectable";
6
+ import * as Option from "effect/Option";
7
+ import * as Pipeable from "effect/Pipeable";
8
+ import * as References from "effect/References";
9
+ import * as Schema from "effect/Schema";
10
+ import * as SchemaIssue from "effect/SchemaIssue";
11
+ import * as SchemaParser from "effect/SchemaParser";
12
+ import * as Stream from "effect/Stream";
13
+ import * as Utils from "effect/Utils";
14
+ const ErrorTypeId = "~@effect/platform-browser/IndexedDbQueryBuilder/IndexedDbQueryError";
15
+ const CommonProto = {
16
+ [Symbol.iterator]() {
17
+ return new Utils.SingleShotGen(this);
18
+ },
19
+ ...Pipeable.Prototype,
20
+ ...BaseProto,
21
+ toJSON() {
22
+ return {
23
+ _id: "IndexedDbQueryBuilder"
24
+ };
25
+ }
26
+ };
27
+ /**
28
+ * @since 4.0.0
29
+ * @category errors
30
+ */
31
+ export class IndexedDbQueryError extends /*#__PURE__*/Data.TaggedError("IndexedDbQueryError") {
32
+ /**
33
+ * @since 4.0.0
34
+ */
35
+ [ErrorTypeId] = ErrorTypeId;
36
+ message = this.reason;
37
+ }
38
+ /**
39
+ * @since 4.0.0
40
+ * @category models
41
+ */
42
+ export class IndexedDbTransaction extends /*#__PURE__*/Context.Service()("@effect/platform-browser/IndexedDbQueryBuilder/IndexedDbTransaction") {}
43
+ const applyDelete = query => Effect.callback(resume => {
44
+ const database = query.delete.from.database;
45
+ const IDBKeyRange = query.delete.from.IDBKeyRange;
46
+ const transaction = getOrCreateTransaction(database.current, [query.delete.from.table.tableName], "readwrite", {
47
+ durability: query.delete.from.table.durability
48
+ });
49
+ const objectStore = transaction.objectStore(query.delete.from.table.tableName);
50
+ const predicate = query.predicate;
51
+ let keyRange = undefined;
52
+ if (query.only !== undefined) {
53
+ keyRange = IDBKeyRange.only(query.only);
54
+ } else if (query.lowerBound !== undefined && query.upperBound !== undefined) {
55
+ keyRange = IDBKeyRange.bound(query.lowerBound, query.upperBound, query.excludeLowerBound, query.excludeUpperBound);
56
+ } else if (query.lowerBound !== undefined) {
57
+ keyRange = IDBKeyRange.lowerBound(query.lowerBound, query.excludeLowerBound);
58
+ } else if (query.upperBound !== undefined) {
59
+ keyRange = IDBKeyRange.upperBound(query.upperBound, query.excludeUpperBound);
60
+ }
61
+ let request;
62
+ if (query.limitValue !== undefined || predicate) {
63
+ const cursorRequest = objectStore.openCursor();
64
+ let count = 0;
65
+ cursorRequest.onerror = () => {
66
+ resume(Effect.fail(new IndexedDbQueryError({
67
+ reason: "TransactionError",
68
+ cause: cursorRequest.error
69
+ })));
70
+ };
71
+ cursorRequest.onsuccess = () => {
72
+ const cursor = cursorRequest.result;
73
+ if (cursor === null) {
74
+ return resume(Effect.void);
75
+ }
76
+ if (predicate === undefined || predicate(cursor.value)) {
77
+ const deleteRequest = cursor.delete();
78
+ deleteRequest.onerror = () => {
79
+ resume(Effect.fail(new IndexedDbQueryError({
80
+ reason: "TransactionError",
81
+ cause: deleteRequest.error
82
+ })));
83
+ };
84
+ count += 1;
85
+ }
86
+ if (query.limitValue === undefined || count < query.limitValue) {
87
+ return cursor.continue();
88
+ }
89
+ resume(Effect.void);
90
+ };
91
+ } else if (keyRange !== undefined) {
92
+ request = objectStore.delete(keyRange);
93
+ request.onerror = event => {
94
+ resume(Effect.fail(new IndexedDbQueryError({
95
+ reason: "TransactionError",
96
+ cause: event
97
+ })));
98
+ };
99
+ request.onsuccess = () => {
100
+ resume(Effect.succeed(request.result));
101
+ };
102
+ } else {
103
+ resume(Effect.die(new Error("No key range provided for delete operation")));
104
+ }
105
+ });
106
+ const getReadonlyObjectStore = query => {
107
+ const database = query.from.database;
108
+ const IDBKeyRange = query.from.IDBKeyRange;
109
+ const transaction = getOrCreateTransaction(database.current, [query.from.table.tableName], "readonly", {
110
+ durability: query.from.table.durability
111
+ });
112
+ const objectStore = transaction.objectStore(query.from.table.tableName);
113
+ let keyRange = undefined;
114
+ let store;
115
+ if (query.only !== undefined) {
116
+ keyRange = IDBKeyRange.only(query.only);
117
+ } else if (query.lowerBound !== undefined && query.upperBound !== undefined) {
118
+ keyRange = IDBKeyRange.bound(query.lowerBound, query.upperBound, query.excludeLowerBound, query.excludeUpperBound);
119
+ } else if (query.lowerBound !== undefined) {
120
+ keyRange = IDBKeyRange.lowerBound(query.lowerBound, query.excludeLowerBound);
121
+ } else if (query.upperBound !== undefined) {
122
+ keyRange = IDBKeyRange.upperBound(query.upperBound, query.excludeUpperBound);
123
+ }
124
+ if (query.index !== undefined) {
125
+ store = objectStore.index(query.index);
126
+ } else {
127
+ store = objectStore;
128
+ }
129
+ return {
130
+ store,
131
+ keyRange
132
+ };
133
+ };
134
+ const applySelect = /*#__PURE__*/Effect.fnUntraced(function* (query) {
135
+ const keyPath = query.from.table.keyPath;
136
+ const predicate = query.predicate;
137
+ const data = predicate || keyPath === undefined || query.offsetValue !== undefined ? yield* Effect.callback(resume => {
138
+ const {
139
+ keyRange,
140
+ store
141
+ } = getReadonlyObjectStore(query);
142
+ const cursorRequest = store.openCursor(keyRange, query.reverseValue ? "prev" : "next");
143
+ const results = [];
144
+ let count = 0;
145
+ let offsetApplied = false;
146
+ cursorRequest.onerror = () => {
147
+ resume(Effect.fail(new IndexedDbQueryError({
148
+ reason: "TransactionError",
149
+ cause: cursorRequest.error
150
+ })));
151
+ };
152
+ cursorRequest.onsuccess = () => {
153
+ const cursor = cursorRequest.result;
154
+ if (cursor === null) {
155
+ return resume(Effect.succeed(results));
156
+ }
157
+ if (query.offsetValue && !offsetApplied) {
158
+ offsetApplied = true;
159
+ return cursor.advance(query.offsetValue);
160
+ }
161
+ if (predicate === undefined || predicate(cursor.value)) {
162
+ results.push(keyPath === undefined ? {
163
+ ...cursor.value,
164
+ key: cursor.key
165
+ } : cursor.value);
166
+ count += 1;
167
+ }
168
+ if (query.limitValue === undefined || count < query.limitValue) {
169
+ return cursor.continue();
170
+ }
171
+ resume(Effect.succeed(results));
172
+ };
173
+ }) : yield* Effect.callback(resume => {
174
+ const {
175
+ keyRange,
176
+ store
177
+ } = getReadonlyObjectStore(query);
178
+ const request = store.getAll(keyRange, query.limitValue);
179
+ request.onerror = event => {
180
+ resume(Effect.fail(new IndexedDbQueryError({
181
+ reason: "TransactionError",
182
+ cause: event
183
+ })));
184
+ };
185
+ request.onsuccess = () => {
186
+ if (query.reverseValue) {
187
+ request.result.reverse();
188
+ }
189
+ resume(Effect.succeed(request.result));
190
+ };
191
+ });
192
+ const tableSchema = query.from.table.arraySchema;
193
+ return yield* Schema.decodeUnknownEffect(tableSchema)(data).pipe(Effect.mapError(error => new IndexedDbQueryError({
194
+ reason: "DecodeError",
195
+ cause: error
196
+ })));
197
+ });
198
+ const getFirst = /*#__PURE__*/Effect.fnUntraced(function* (query) {
199
+ const keyPath = query.select.from.table.keyPath;
200
+ const data = yield* Effect.callback(resume => {
201
+ const {
202
+ keyRange,
203
+ store
204
+ } = getReadonlyObjectStore(query.select);
205
+ if (keyRange !== undefined) {
206
+ const request = store.get(keyRange);
207
+ request.onerror = event => {
208
+ resume(Effect.fail(new IndexedDbQueryError({
209
+ reason: "TransactionError",
210
+ cause: event
211
+ })));
212
+ };
213
+ request.onsuccess = () => {
214
+ resume(Effect.succeed(request.result));
215
+ };
216
+ } else {
217
+ const request = store.openCursor();
218
+ request.onerror = event => {
219
+ resume(Effect.fail(new IndexedDbQueryError({
220
+ reason: "TransactionError",
221
+ cause: event
222
+ })));
223
+ };
224
+ request.onsuccess = () => {
225
+ const value = request.result?.value;
226
+ const key = request.result?.key;
227
+ if (value === undefined) {
228
+ resume(Effect.fail(new IndexedDbQueryError({
229
+ reason: "NotFoundError",
230
+ cause: request.error
231
+ })));
232
+ } else {
233
+ resume(Effect.succeed(keyPath === undefined ? {
234
+ ...value,
235
+ key
236
+ } : value));
237
+ }
238
+ };
239
+ }
240
+ });
241
+ return yield* Schema.decodeUnknownEffect(query.select.from.table.readSchema)(data).pipe(Effect.mapError(error => new IndexedDbQueryError({
242
+ reason: "DecodeError",
243
+ cause: error
244
+ })));
245
+ });
246
+ const applyModify = /*#__PURE__*/Effect.fnUntraced(function* ({
247
+ query,
248
+ value
249
+ }) {
250
+ const autoIncrement = query.from.table.autoIncrement;
251
+ const keyPath = query.from.table.keyPath;
252
+ const table = query.from.table;
253
+ const schema = autoIncrement && value[keyPath] === undefined ? table.autoincrementSchema : table.tableSchema;
254
+ const encodedValue = yield* SchemaParser.makeEffect(autoIncrement && value[keyPath] === undefined ? table.autoincrementSchema : table.tableSchema)(value).pipe(Effect.flatMap(Schema.encodeUnknownEffect(schema)), Effect.mapError(error => new IndexedDbQueryError({
255
+ reason: "EncodeError",
256
+ cause: error
257
+ })));
258
+ return yield* Effect.callback(resume => {
259
+ const database = query.from.database;
260
+ const transaction = getOrCreateTransaction(database.current, [query.from.table.tableName], "readwrite", {
261
+ durability: query.from.table.durability
262
+ });
263
+ const objectStore = transaction.objectStore(query.from.table.tableName);
264
+ let request;
265
+ if (query.operation === "add") {
266
+ request = objectStore.add(encodedValue, keyPath === undefined ? value["key"] : undefined);
267
+ } else if (query.operation === "put") {
268
+ request = objectStore.put(encodedValue, keyPath === undefined ? value["key"] : undefined);
269
+ } else {
270
+ return resume(Effect.die(new Error("Invalid modify operation")));
271
+ }
272
+ request.onerror = event => {
273
+ resume(Effect.fail(new IndexedDbQueryError({
274
+ reason: "TransactionError",
275
+ cause: event
276
+ })));
277
+ };
278
+ request.onsuccess = () => {
279
+ resume(Effect.succeed(request.result));
280
+ };
281
+ });
282
+ });
283
+ const applyModifyAll = /*#__PURE__*/Effect.fnUntraced(function* ({
284
+ query,
285
+ values
286
+ }) {
287
+ const autoIncrement = query.from.table.autoIncrement;
288
+ const keyPath = query.from.table.keyPath;
289
+ const schema = query.from.table.tableSchema;
290
+ const encodedValues = new Array(values.length);
291
+ const makeValue = SchemaParser.makeEffect(schema);
292
+ const encodeValue = SchemaParser.encodeUnknownEffect(schema);
293
+ const makeValueAutoincrement = SchemaParser.makeEffect(query.from.table.autoincrementSchema);
294
+ const encodeValueAutoincrement = SchemaParser.encodeUnknownEffect(query.from.table.autoincrementSchema);
295
+ for (let i = 0; i < values.length; i++) {
296
+ const value = values[i];
297
+ if (autoIncrement && value[keyPath] === undefined) {
298
+ encodedValues[i] = yield* encodeValueAutoincrement(yield* makeValueAutoincrement(value));
299
+ } else {
300
+ encodedValues[i] = yield* encodeValue(yield* makeValue(value));
301
+ }
302
+ }
303
+ return yield* Effect.callback(resume => {
304
+ const database = query.from.database;
305
+ const transaction = getOrCreateTransaction(database.current, [query.from.table.tableName], "readwrite", {
306
+ durability: query.from.table.durability
307
+ });
308
+ const objectStore = transaction.objectStore(query.from.table.tableName);
309
+ const results = [];
310
+ if (query.operation === "add") {
311
+ for (let i = 0; i < encodedValues.length; i++) {
312
+ const request = objectStore.add(encodedValues[i], keyPath === undefined ? values[i]["key"] : undefined);
313
+ request.onerror = () => {
314
+ resume(Effect.fail(new IndexedDbQueryError({
315
+ reason: "TransactionError",
316
+ cause: request.error
317
+ })));
318
+ };
319
+ request.onsuccess = () => {
320
+ results.push(request.result);
321
+ };
322
+ }
323
+ } else if (query.operation === "put") {
324
+ for (let i = 0; i < encodedValues.length; i++) {
325
+ const request = objectStore.put(encodedValues[i], keyPath === undefined ? values[i]["key"] : undefined);
326
+ request.onerror = () => {
327
+ resume(Effect.fail(new IndexedDbQueryError({
328
+ reason: "TransactionError",
329
+ cause: request.error
330
+ })));
331
+ };
332
+ request.onsuccess = () => {
333
+ results.push(request.result);
334
+ };
335
+ }
336
+ } else {
337
+ return resume(Effect.die(new Error("Invalid modify all operation")));
338
+ }
339
+ objectStore.transaction.onerror = () => {
340
+ resume(Effect.fail(new IndexedDbQueryError({
341
+ reason: "TransactionError",
342
+ cause: objectStore.transaction.error
343
+ })));
344
+ };
345
+ objectStore.transaction.oncomplete = () => {
346
+ resume(Effect.succeed(results));
347
+ };
348
+ });
349
+ }, /*#__PURE__*/Effect.catchIf(SchemaIssue.isIssue, issue => Effect.fail(new IndexedDbQueryError({
350
+ reason: "EncodeError",
351
+ cause: new Schema.SchemaError(issue)
352
+ }))));
353
+ const applyClear = options => Effect.callback(resume => {
354
+ const database = options.database;
355
+ const transaction = getOrCreateTransaction(database, [options.table.tableName], "readwrite", {
356
+ durability: options.table.durability
357
+ });
358
+ const objectStore = transaction.objectStore(options.table.tableName);
359
+ const request = objectStore.clear();
360
+ request.onerror = event => {
361
+ resume(Effect.fail(new IndexedDbQueryError({
362
+ reason: "TransactionError",
363
+ cause: event
364
+ })));
365
+ };
366
+ request.onsuccess = () => {
367
+ resume(Effect.void);
368
+ };
369
+ });
370
+ const applyClearAll = options => Effect.callback(resume => {
371
+ const database = options.database;
372
+ const tables = database.objectStoreNames;
373
+ const transaction = getOrCreateTransaction(database, [...tables], "readwrite");
374
+ for (let t = 0; t < tables.length; t++) {
375
+ const objectStore = transaction.objectStore(tables[t]);
376
+ const request = objectStore.clear();
377
+ request.onerror = () => {
378
+ resume(Effect.fail(new IndexedDbQueryError({
379
+ reason: "TransactionError",
380
+ cause: request.error
381
+ })));
382
+ };
383
+ }
384
+ transaction.onerror = () => {
385
+ resume(Effect.fail(new IndexedDbQueryError({
386
+ reason: "TransactionError",
387
+ cause: transaction.error
388
+ })));
389
+ };
390
+ transaction.oncomplete = () => {
391
+ resume(Effect.void);
392
+ };
393
+ });
394
+ const getCount = query => Effect.callback(resume => {
395
+ const {
396
+ keyRange,
397
+ store
398
+ } = getReadonlyObjectStore(query);
399
+ const request = store.count(keyRange);
400
+ request.onerror = event => {
401
+ resume(Effect.fail(new IndexedDbQueryError({
402
+ reason: "TransactionError",
403
+ cause: event
404
+ })));
405
+ };
406
+ request.onsuccess = () => {
407
+ resume(Effect.succeed(request.result));
408
+ };
409
+ });
410
+ const FromProto = {
411
+ ...CommonProto,
412
+ select(index) {
413
+ return makeSelect({
414
+ from: this,
415
+ index
416
+ });
417
+ },
418
+ count(index) {
419
+ return makeCount({
420
+ from: this,
421
+ index
422
+ });
423
+ },
424
+ delete(index) {
425
+ return makeDeletePartial({
426
+ from: this,
427
+ index
428
+ });
429
+ },
430
+ insert(value) {
431
+ return makeModify({
432
+ from: this,
433
+ value,
434
+ operation: "add"
435
+ });
436
+ },
437
+ upsert(value) {
438
+ return makeModify({
439
+ from: this,
440
+ value,
441
+ operation: "put"
442
+ });
443
+ },
444
+ insertAll(values) {
445
+ return makeModifyAll({
446
+ from: this,
447
+ values,
448
+ operation: "add"
449
+ });
450
+ },
451
+ upsertAll(values) {
452
+ return makeModifyAll({
453
+ from: this,
454
+ values,
455
+ operation: "put"
456
+ });
457
+ },
458
+ get clear() {
459
+ const self = this;
460
+ return applyClear({
461
+ database: self.database.current,
462
+ table: self.table
463
+ });
464
+ }
465
+ };
466
+ const makeFrom = options => {
467
+ const self = Object.create(FromProto);
468
+ self.table = options.table;
469
+ self.database = options.database;
470
+ self.IDBKeyRange = options.IDBKeyRange;
471
+ self.reactivity = options.reactivity;
472
+ return self;
473
+ };
474
+ const DeletePartialProto = {
475
+ ...CommonProto,
476
+ limit(limit) {
477
+ return makeDelete({
478
+ delete: this,
479
+ limitValue: limit
480
+ });
481
+ },
482
+ equals(value) {
483
+ return makeDelete({
484
+ delete: this,
485
+ only: value
486
+ });
487
+ },
488
+ gte(value) {
489
+ return makeDelete({
490
+ delete: this,
491
+ lowerBound: value,
492
+ excludeLowerBound: false
493
+ });
494
+ },
495
+ lte(value) {
496
+ return makeDelete({
497
+ delete: this,
498
+ upperBound: value,
499
+ excludeUpperBound: false
500
+ });
501
+ },
502
+ gt(value) {
503
+ return makeDelete({
504
+ delete: this,
505
+ lowerBound: value,
506
+ excludeLowerBound: true
507
+ });
508
+ },
509
+ lt(value) {
510
+ return makeDelete({
511
+ delete: this,
512
+ upperBound: value,
513
+ excludeUpperBound: true
514
+ });
515
+ },
516
+ between(lowerBound, upperBound, queryOptions) {
517
+ return makeDelete({
518
+ delete: this,
519
+ lowerBound,
520
+ upperBound,
521
+ excludeLowerBound: queryOptions?.excludeLowerBound ?? false,
522
+ excludeUpperBound: queryOptions?.excludeUpperBound ?? false
523
+ });
524
+ }
525
+ };
526
+ const makeDeletePartial = options => {
527
+ const self = Object.create(DeletePartialProto);
528
+ self.from = options.from;
529
+ self.index = options.index;
530
+ return self;
531
+ };
532
+ const DeleteProto = {
533
+ ...CommonProto,
534
+ asEffect() {
535
+ return applyDelete(this);
536
+ },
537
+ limit(limit) {
538
+ return makeDelete({
539
+ ...this,
540
+ limitValue: limit
541
+ });
542
+ },
543
+ filter(filter) {
544
+ const prev = this.predicate;
545
+ return makeDelete({
546
+ delete: this.delete,
547
+ predicate: prev ? item => prev(item) && filter(item) : filter
548
+ });
549
+ },
550
+ invalidate(keys) {
551
+ keys ??= this.only !== undefined ? {
552
+ [this.delete.from.table.tableName]: [this.only]
553
+ } : [this.delete.from.table.tableName];
554
+ return this.delete.from.reactivity.mutation(keys, this.asEffect());
555
+ }
556
+ };
557
+ const makeDelete = options => {
558
+ const self = Object.create(DeleteProto);
559
+ self.delete = options.delete;
560
+ self.limitValue = options.limitValue;
561
+ self.only = options.only;
562
+ self.lowerBound = options.lowerBound;
563
+ self.upperBound = options.upperBound;
564
+ self.excludeLowerBound = options.excludeLowerBound ?? false;
565
+ self.excludeUpperBound = options.excludeUpperBound ?? false;
566
+ self.predicate = options.predicate;
567
+ return self;
568
+ };
569
+ const CountProto = {
570
+ ...CommonProto,
571
+ asEffect() {
572
+ return getCount(this);
573
+ },
574
+ equals(value) {
575
+ return makeCount({
576
+ from: this.from,
577
+ index: this.index,
578
+ only: value
579
+ });
580
+ },
581
+ gte(value) {
582
+ return makeCount({
583
+ from: this.from,
584
+ index: this.index,
585
+ lowerBound: value,
586
+ excludeLowerBound: false
587
+ });
588
+ },
589
+ lte(value) {
590
+ return makeCount({
591
+ from: this.from,
592
+ index: this.index,
593
+ upperBound: value,
594
+ excludeUpperBound: false
595
+ });
596
+ },
597
+ gt(value) {
598
+ return makeCount({
599
+ from: this.from,
600
+ index: this.index,
601
+ lowerBound: value,
602
+ excludeLowerBound: true
603
+ });
604
+ },
605
+ lt(value) {
606
+ return makeCount({
607
+ from: this.from,
608
+ index: this.index,
609
+ upperBound: value,
610
+ excludeUpperBound: true
611
+ });
612
+ },
613
+ between(lowerBound, upperBound, queryOptions) {
614
+ return makeCount({
615
+ from: this.from,
616
+ index: this.index,
617
+ lowerBound,
618
+ upperBound,
619
+ excludeLowerBound: queryOptions?.excludeLowerBound ?? false,
620
+ excludeUpperBound: queryOptions?.excludeUpperBound ?? false
621
+ });
622
+ }
623
+ };
624
+ const makeCount = options => {
625
+ const self = Object.create(CountProto);
626
+ self.from = options.from;
627
+ self.index = options.index;
628
+ self.only = options.only;
629
+ self.lowerBound = options.lowerBound;
630
+ self.upperBound = options.upperBound;
631
+ self.excludeLowerBound = options.excludeLowerBound;
632
+ self.excludeUpperBound = options.excludeUpperBound;
633
+ return self;
634
+ };
635
+ const SelectProto = {
636
+ ...CommonProto,
637
+ limit(limit) {
638
+ return makeSelect({
639
+ ...this,
640
+ limitValue: limit
641
+ });
642
+ },
643
+ offset(offset) {
644
+ return makeSelect({
645
+ ...this,
646
+ offsetValue: offset
647
+ });
648
+ },
649
+ equals(value) {
650
+ return makeSelect({
651
+ ...this,
652
+ only: value
653
+ });
654
+ },
655
+ gte(value) {
656
+ return makeSelect({
657
+ ...this,
658
+ lowerBound: value,
659
+ excludeLowerBound: false
660
+ });
661
+ },
662
+ lte(value) {
663
+ return makeSelect({
664
+ ...this,
665
+ upperBound: value,
666
+ excludeUpperBound: false
667
+ });
668
+ },
669
+ gt(value) {
670
+ return makeSelect({
671
+ ...this,
672
+ lowerBound: value,
673
+ excludeLowerBound: true
674
+ });
675
+ },
676
+ lt(value) {
677
+ return makeSelect({
678
+ ...this,
679
+ upperBound: value,
680
+ excludeUpperBound: true
681
+ });
682
+ },
683
+ between(lowerBound, upperBound, queryOptions) {
684
+ return makeSelect({
685
+ ...this,
686
+ lowerBound,
687
+ upperBound,
688
+ excludeLowerBound: queryOptions?.excludeLowerBound ?? false,
689
+ excludeUpperBound: queryOptions?.excludeUpperBound ?? false
690
+ });
691
+ },
692
+ reverse() {
693
+ return makeSelect({
694
+ ...this,
695
+ reverseValue: true
696
+ });
697
+ },
698
+ first() {
699
+ return makeFirst({
700
+ select: this
701
+ });
702
+ },
703
+ filter(filter) {
704
+ const prev = this.predicate;
705
+ return makeSelect({
706
+ ...this,
707
+ predicate: prev ? item => prev(item) && filter(item) : filter
708
+ });
709
+ },
710
+ asEffect() {
711
+ return applySelect(this);
712
+ },
713
+ stream(options) {
714
+ const limit = this.limitValue;
715
+ const chunkSize = Math.min(options?.chunkSize ?? 100, limit ?? Number.MAX_SAFE_INTEGER);
716
+ const initial = this.limit(chunkSize);
717
+ return Stream.suspend(() => {
718
+ let total = 0;
719
+ return Stream.paginate(initial, select => Effect.map(applySelect(select), data => {
720
+ total += data.length;
721
+ select.offsetValue = total;
722
+ const reachedLimit = limit && total >= limit;
723
+ const isPartial = data.length < chunkSize;
724
+ return [data, isPartial || reachedLimit ? Option.none() : Option.some(select)];
725
+ }));
726
+ });
727
+ },
728
+ reactive(keys) {
729
+ keys ??= [this.from.table.tableName];
730
+ return this.from.reactivity.stream(keys, this.asEffect());
731
+ },
732
+ reactiveQueue(keys) {
733
+ keys ??= [this.from.table.tableName];
734
+ return this.from.reactivity.query(keys, this.asEffect());
735
+ }
736
+ };
737
+ const makeSelect = options => {
738
+ const self = Object.create(SelectProto);
739
+ self.from = options.from;
740
+ self.index = options.index;
741
+ self.only = options.only;
742
+ self.limitValue = options.limitValue;
743
+ self.offsetValue = options.offsetValue;
744
+ self.reverseValue = options.reverseValue;
745
+ self.lowerBound = options.lowerBound;
746
+ self.upperBound = options.upperBound;
747
+ self.excludeLowerBound = options.excludeLowerBound;
748
+ self.excludeUpperBound = options.excludeUpperBound;
749
+ self.predicate = options.predicate;
750
+ return self;
751
+ };
752
+ const FirstProto = {
753
+ ...CommonProto,
754
+ asEffect() {
755
+ return getFirst(this);
756
+ },
757
+ reactive(keys) {
758
+ keys ??= this.select.only !== undefined ? [`${this.select.from.table.tableName}:${String(this.select.only)}`] : [this.select.from.table.tableName];
759
+ return this.select.from.reactivity.stream(keys, this.asEffect());
760
+ },
761
+ reactiveQueue(keys) {
762
+ keys ??= this.select.only !== undefined ? [`${this.select.from.table.tableName}:${this.select.only}`] : [this.select.from.table.tableName];
763
+ return this.select.from.reactivity.query(keys, this.asEffect());
764
+ }
765
+ };
766
+ const makeFirst = options => {
767
+ const self = Object.create(FirstProto);
768
+ self.select = options.select;
769
+ return self;
770
+ };
771
+ const ModifyProto = {
772
+ ...CommonProto,
773
+ asEffect() {
774
+ return applyModify({
775
+ query: this,
776
+ value: this.value
777
+ });
778
+ },
779
+ invalidate(keys) {
780
+ const keyPath = this.from.table.keyPath;
781
+ keys ??= typeof keyPath === "string" && this.value[keyPath] !== undefined ? {
782
+ [this.from.table.tableName]: [this.value[keyPath]]
783
+ } : [this.from.table.tableName];
784
+ return this.from.reactivity.mutation(keys, this.asEffect());
785
+ }
786
+ };
787
+ const makeModify = options => {
788
+ const self = Object.create(ModifyProto);
789
+ self.from = options.from;
790
+ self.value = options.value;
791
+ self.operation = options.operation;
792
+ return self;
793
+ };
794
+ const ModifyAllProto = {
795
+ ...CommonProto,
796
+ asEffect() {
797
+ return applyModifyAll({
798
+ query: this,
799
+ values: this.values
800
+ });
801
+ },
802
+ invalidate(keys) {
803
+ keys ??= [this.from.table.tableName];
804
+ return this.from.reactivity.mutation(keys, this.asEffect());
805
+ }
806
+ };
807
+ const makeModifyAll = options => {
808
+ const self = Object.create(ModifyAllProto);
809
+ self.from = options.from;
810
+ self.values = options.values;
811
+ self.operation = options.operation;
812
+ return self;
813
+ };
814
+ const QueryBuilderProto = {
815
+ ...CommonProto,
816
+ use(f) {
817
+ return Effect.try({
818
+ try: () => f(this.database.current),
819
+ catch: error => new IndexedDbQueryError({
820
+ reason: "UnknownError",
821
+ cause: error
822
+ })
823
+ });
824
+ },
825
+ from(table) {
826
+ return makeFrom({
827
+ database: this.database,
828
+ IDBKeyRange: this.IDBKeyRange,
829
+ table: this.tables.get(table),
830
+ reactivity: this.reactivity
831
+ });
832
+ },
833
+ get clearAll() {
834
+ const self = this;
835
+ return applyClearAll({
836
+ database: self.database.current
837
+ });
838
+ },
839
+ withTransaction(options) {
840
+ return effect => Effect.suspend(() => {
841
+ const transaction = this.database.current.transaction(options.tables, options.mode, options);
842
+ return Effect.provideService(effect, IndexedDbTransaction, transaction);
843
+ }).pipe(
844
+ // To prevent async gaps between transaction queries
845
+ Effect.provideService(References.PreventSchedulerYield, true));
846
+ }
847
+ };
848
+ /**
849
+ * @since 4.0.0
850
+ * @category constructors
851
+ */
852
+ export const make = ({
853
+ IDBKeyRange,
854
+ database,
855
+ tables,
856
+ reactivity
857
+ }) => {
858
+ const self = Object.create(QueryBuilderProto);
859
+ self.tables = tables;
860
+ self.database = database;
861
+ self.reactivity = reactivity;
862
+ self.IDBKeyRange = IDBKeyRange;
863
+ return self;
864
+ };
865
+ const getOrCreateTransaction = (database, tables, mode, options) => {
866
+ const fiber = Fiber.getCurrent();
867
+ return Context.getOrUndefined(fiber.context, IndexedDbTransaction) ?? database.transaction(tables, mode, options);
868
+ };
869
+ //# sourceMappingURL=IndexedDbQueryBuilder.js.map