@effect/platform-browser 4.0.0-beta.102 → 4.0.0-beta.103

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 (59) hide show
  1. package/dist/BrowserCrypto.d.ts +1 -1
  2. package/dist/BrowserCrypto.d.ts.map +1 -1
  3. package/dist/BrowserCrypto.js +4 -2
  4. package/dist/BrowserCrypto.js.map +1 -1
  5. package/dist/BrowserHttpClient.d.ts +5 -5
  6. package/dist/BrowserHttpClient.js +5 -5
  7. package/dist/BrowserHttpClient.js.map +1 -1
  8. package/dist/BrowserKeyValueStore.d.ts.map +1 -1
  9. package/dist/BrowserKeyValueStore.js +38 -9
  10. package/dist/BrowserKeyValueStore.js.map +1 -1
  11. package/dist/BrowserPersistence.js.map +1 -1
  12. package/dist/BrowserRuntime.d.ts +3 -3
  13. package/dist/BrowserRuntime.js +1 -1
  14. package/dist/BrowserRuntime.js.map +1 -1
  15. package/dist/BrowserSocket.js.map +1 -1
  16. package/dist/BrowserStream.d.ts +2 -2
  17. package/dist/BrowserStream.js +2 -2
  18. package/dist/BrowserStream.js.map +1 -1
  19. package/dist/BrowserWorker.js.map +1 -1
  20. package/dist/BrowserWorkerRunner.d.ts.map +1 -1
  21. package/dist/BrowserWorkerRunner.js +2 -1
  22. package/dist/BrowserWorkerRunner.js.map +1 -1
  23. package/dist/Clipboard.d.ts +1 -1
  24. package/dist/Clipboard.js.map +1 -1
  25. package/dist/Geolocation.d.ts +1 -1
  26. package/dist/Geolocation.js.map +1 -1
  27. package/dist/IndexedDb.d.ts +2 -2
  28. package/dist/IndexedDb.js +1 -1
  29. package/dist/IndexedDb.js.map +1 -1
  30. package/dist/IndexedDbDatabase.d.ts +3 -3
  31. package/dist/IndexedDbDatabase.d.ts.map +1 -1
  32. package/dist/IndexedDbDatabase.js +13 -7
  33. package/dist/IndexedDbDatabase.js.map +1 -1
  34. package/dist/IndexedDbQueryBuilder.d.ts +9 -9
  35. package/dist/IndexedDbQueryBuilder.d.ts.map +1 -1
  36. package/dist/IndexedDbQueryBuilder.js +38 -13
  37. package/dist/IndexedDbQueryBuilder.js.map +1 -1
  38. package/dist/IndexedDbTable.d.ts +9 -9
  39. package/dist/IndexedDbTable.js.map +1 -1
  40. package/dist/IndexedDbVersion.d.ts +4 -4
  41. package/dist/IndexedDbVersion.js.map +1 -1
  42. package/dist/Permissions.d.ts +1 -1
  43. package/dist/Permissions.js.map +1 -1
  44. package/dist/index.js.map +1 -1
  45. package/package.json +5 -6
  46. package/src/BrowserCrypto.ts +4 -2
  47. package/src/BrowserHttpClient.ts +5 -5
  48. package/src/BrowserKeyValueStore.ts +50 -8
  49. package/src/BrowserRuntime.ts +3 -3
  50. package/src/BrowserStream.ts +2 -2
  51. package/src/BrowserWorkerRunner.ts +2 -1
  52. package/src/Clipboard.ts +1 -1
  53. package/src/Geolocation.ts +1 -1
  54. package/src/IndexedDb.ts +2 -2
  55. package/src/IndexedDbDatabase.ts +15 -9
  56. package/src/IndexedDbQueryBuilder.ts +64 -21
  57. package/src/IndexedDbTable.ts +9 -9
  58. package/src/IndexedDbVersion.ts +4 -4
  59. package/src/Permissions.ts +1 -1
@@ -31,12 +31,6 @@ const SchemaProto = {
31
31
  [TypeId]: {
32
32
  _A: (_: never) => _
33
33
  },
34
- ...Effectable.Prototype<IndexedDbSchema<any, any, any>>({
35
- label: "IndexedDbSchema",
36
- evaluate() {
37
- return this.getQueryBuilder
38
- }
39
- }),
40
34
  get getQueryBuilder() {
41
35
  const self = this as unknown as IndexedDbSchema<any, any, any>
42
36
  return IndexedDbDatabase.useSync(({ database, IDBKeyRange, reactivity }) =>
@@ -48,6 +42,12 @@ const SchemaProto = {
48
42
  })
49
43
  )
50
44
  },
45
+ ...Effectable.Prototype<IndexedDbSchema<any, any, any>>({
46
+ label: "IndexedDbSchema",
47
+ evaluate() {
48
+ return this.getQueryBuilder
49
+ }
50
+ }),
51
51
  add<Version extends IndexedDbVersion.AnyWithProps>(
52
52
  this: IndexedDbSchema<any, any, any>,
53
53
  version: Version,
@@ -126,7 +126,7 @@ export class IndexedDbDatabaseError extends Data.TaggedError(
126
126
  * @see {@link IndexedDb.IndexedDb} for the lower-level browser IndexedDB primitives
127
127
  * @see {@link make} for creating a schema that provides this service as a layer
128
128
  *
129
- * @category models
129
+ * @category services
130
130
  * @since 4.0.0
131
131
  */
132
132
  export class IndexedDbDatabase extends Context.Service<
@@ -234,7 +234,7 @@ export interface Transaction<
234
234
  /**
235
235
  * Extracts the string-literal index names defined by an `IndexedDbTable`.
236
236
  *
237
- * @category models
237
+ * @category utility types
238
238
  * @since 4.0.0
239
239
  */
240
240
  export type IndexFromTable<Table extends IndexedDbTable.AnyWithProps> = IsStringLiteral<
@@ -245,7 +245,7 @@ export type IndexFromTable<Table extends IndexedDbTable.AnyWithProps> = IsString
245
245
  /**
246
246
  * Extracts the valid index names for a table name within an IndexedDB version.
247
247
  *
248
- * @category models
248
+ * @category utility types
249
249
  * @since 4.0.0
250
250
  */
251
251
  export type IndexFromTableName<
@@ -478,6 +478,12 @@ const layer = <DatabaseName extends string>(
478
478
  Effect.provideService(IndexedDbQueryBuilder.IndexedDbTransaction, transaction)
479
479
  )
480
480
  fiber = runForkWith(effect)
481
+ fiber.addObserver((exit) => {
482
+ if (exit._tag === "Failure") {
483
+ transaction.abort()
484
+ resume(exit)
485
+ }
486
+ })
481
487
  fiber.currentDispatcher.flush()
482
488
  }
483
489
 
@@ -136,13 +136,17 @@ export interface IndexedDbQueryBuilder<
136
136
  readonly tables: Tables
137
137
  readonly mode: Mode
138
138
  readonly durability?: IDBTransactionDurability
139
- }) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, IndexedDbTransaction>>
139
+ }) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<
140
+ A,
141
+ E | IndexedDbQueryError,
142
+ Exclude<R, IndexedDbTransaction>
143
+ >
140
144
  }
141
145
 
142
146
  /**
143
147
  * Valid key-path type for a table schema, using encoded fields whose values are IndexedDB-valid keys.
144
148
  *
145
- * @category models
149
+ * @category utility types
146
150
  * @since 4.0.0
147
151
  */
148
152
  export type KeyPath<TableSchema extends IndexedDbTable.AnySchemaStruct> =
@@ -152,7 +156,7 @@ export type KeyPath<TableSchema extends IndexedDbTable.AnySchemaStruct> =
152
156
  /**
153
157
  * Valid numeric key-path type for a table schema, used for auto-increment key paths.
154
158
  *
155
- * @category models
159
+ * @category utility types
156
160
  * @since 4.0.0
157
161
  */
158
162
  export type KeyPathNumber<TableSchema extends IndexedDbTable.AnySchemaStruct> =
@@ -168,7 +172,7 @@ export declare namespace IndexedDbQuery {
168
172
  /**
169
173
  * Decoded row type returned by select queries, adding a `key` field when the table does not define a key path.
170
174
  *
171
- * @category models
175
+ * @category utility types
172
176
  * @since 4.0.0
173
177
  */
174
178
  export type SelectType<
@@ -181,7 +185,7 @@ export declare namespace IndexedDbQuery {
181
185
  /**
182
186
  * Input type for insert and upsert operations, adjusted for auto-increment keys and out-of-line keys.
183
187
  *
184
- * @category models
188
+ * @category utility types
185
189
  * @since 4.0.0
186
190
  */
187
191
  export type ModifyType<
@@ -215,7 +219,7 @@ export declare namespace IndexedDbQuery {
215
219
  /**
216
220
  * Value type accepted by `equals` comparisons for a table key path or index.
217
221
  *
218
- * @category models
222
+ * @category utility types
219
223
  * @since 4.0.0
220
224
  */
221
225
  export type EqualsType<
@@ -229,7 +233,7 @@ export declare namespace IndexedDbQuery {
229
233
  /**
230
234
  * Value type accepted by range comparisons for a table key path or index, including partial tuples for compound indexes.
231
235
  *
232
- * @category models
236
+ * @category utility types
233
237
  * @since 4.0.0
234
238
  */
235
239
  export type ExtractIndexType<
@@ -248,7 +252,7 @@ export declare namespace IndexedDbQuery {
248
252
  /**
249
253
  * Mutation input type for insert and upsert operations, including any required key fields.
250
254
  *
251
- * @category models
255
+ * @category utility types
252
256
  * @since 4.0.0
253
257
  */
254
258
  export type ModifyWithKey<Table extends IndexedDbTable.AnyWithProps> = ModifyType<Table>
@@ -719,7 +723,7 @@ export declare namespace IndexedDbQuery {
719
723
  /**
720
724
  * Service tag for the active `IDBTransaction` used to share a transaction across IndexedDB query effects.
721
725
  *
722
- * @category models
726
+ * @category services
723
727
  * @since 4.0.0
724
728
  */
725
729
  export class IndexedDbTransaction extends Context.Service<IndexedDbTransaction, globalThis.IDBTransaction>()(
@@ -752,6 +756,7 @@ const applyDelete = (query: IndexedDbQuery.Delete<any, never>) =>
752
756
  durability: query.delete.from.table.durability
753
757
  })
754
758
  const objectStore = transaction.objectStore(query.delete.from.table.tableName)
759
+ const store = query.delete.index === undefined ? objectStore : objectStore.index(query.delete.index)
755
760
  const predicate = query.predicate
756
761
 
757
762
  let keyRange: globalThis.IDBKeyRange | undefined = undefined
@@ -782,8 +787,8 @@ const applyDelete = (query: IndexedDbQuery.Delete<any, never>) =>
782
787
 
783
788
  let request: globalThis.IDBRequest
784
789
 
785
- if (query.limitValue !== undefined || predicate) {
786
- const cursorRequest = objectStore.openCursor()
790
+ if (query.delete.index !== undefined || query.limitValue !== undefined || predicate) {
791
+ const cursorRequest = store.openCursor(keyRange)
787
792
  let count = 0
788
793
 
789
794
  cursorRequest.onerror = () => {
@@ -897,7 +902,7 @@ const applySelect = Effect.fnUntraced(function*(
897
902
  const keyPath = query.from.table.keyPath
898
903
  const predicate = query.predicate
899
904
 
900
- const data = predicate || keyPath === undefined || query.offsetValue !== undefined ?
905
+ const data = predicate || keyPath === undefined || query.offsetValue !== undefined || query.reverseValue ?
901
906
  yield* Effect.callback<Array<any>, IndexedDbQueryError>((resume) => {
902
907
  const { keyRange, store } = getReadonlyObjectStore(query)
903
908
 
@@ -1001,7 +1006,13 @@ const applyFirst = Effect.fnUntraced(function*(
1001
1006
  }
1002
1007
 
1003
1008
  request.onsuccess = () => {
1004
- resume(Effect.succeed(request.result))
1009
+ if (request.result === undefined) {
1010
+ resume(
1011
+ Effect.fail(new Cause.NoSuchElementError(`No such element in table ${query.select.from.table.tableName}`))
1012
+ )
1013
+ } else {
1014
+ resume(Effect.succeed(request.result))
1015
+ }
1005
1016
  }
1006
1017
  } else {
1007
1018
  const request = store.openCursor()
@@ -1331,7 +1342,6 @@ const FromProto: Omit<
1331
1342
  | "countCache"
1332
1343
  | "deleteCache"
1333
1344
  > = {
1334
- ...CommonProto,
1335
1345
  select<Index extends IndexedDbDatabase.IndexFromTable<any>>(
1336
1346
  this: IndexedDbQuery.From<any>,
1337
1347
  index?: Index
@@ -1392,7 +1402,8 @@ const FromProto: Omit<
1392
1402
  database: self.database.current,
1393
1403
  table: self.table
1394
1404
  })
1395
- }
1405
+ },
1406
+ ...CommonProto
1396
1407
  }
1397
1408
 
1398
1409
  const makeFrom = <
@@ -1516,7 +1527,7 @@ const DeleteProto: Omit<
1516
1527
  filter(this: IndexedDbQuery.Delete<any, never>, filter: (value: IndexedDbTable.Encoded<any>) => boolean) {
1517
1528
  const prev = this.predicate
1518
1529
  return makeDelete({
1519
- delete: this.delete,
1530
+ ...this,
1520
1531
  predicate: prev ? (item) => prev(item) && filter(item) : filter
1521
1532
  })
1522
1533
  },
@@ -1760,18 +1771,22 @@ const SelectProto: Omit<
1760
1771
  }) {
1761
1772
  const limit = this.limitValue
1762
1773
  const chunkSize = Math.min(options?.chunkSize ?? 100, limit ?? Number.MAX_SAFE_INTEGER)
1763
- const initial = this.limit(chunkSize)
1774
+ const initialOffset = this.offsetValue ?? 0
1764
1775
  return Stream.suspend(() => {
1765
1776
  let total = 0
1777
+ const initial = this.limit(chunkSize)
1766
1778
  return Stream.paginate(initial, (select) =>
1767
1779
  Effect.map(
1768
1780
  applySelect(select as any),
1769
1781
  (data) => {
1770
1782
  total += data.length
1771
- ;(select as any).offsetValue = total
1772
1783
  const reachedLimit = limit && total >= limit
1773
1784
  const isPartial = data.length < chunkSize
1774
- return [data, isPartial || reachedLimit ? Option.none() : Option.some(select)] as const
1785
+ const next = makeSelect({
1786
+ ...select,
1787
+ offsetValue: initialOffset + total
1788
+ })
1789
+ return [data, isPartial || reachedLimit ? Option.none() : Option.some(next)] as const
1775
1790
  }
1776
1791
  ))
1777
1792
  })
@@ -1951,7 +1966,6 @@ const QueryBuilderProto: Omit<
1951
1966
  | "IDBTransaction"
1952
1967
  | "reactivity"
1953
1968
  > = {
1954
- ...CommonProto,
1955
1969
  use(this: IndexedDbQueryBuilder<any>, f: (database: globalThis.IDBDatabase) => any) {
1956
1970
  return Effect.try({
1957
1971
  try: () => f(this.database.current),
@@ -1979,6 +1993,7 @@ const QueryBuilderProto: Omit<
1979
1993
  const self = this as IndexedDbQueryBuilder<any>
1980
1994
  return applyClearAll({ database: self.database.current })
1981
1995
  },
1996
+ ...CommonProto,
1982
1997
  withTransaction(this: IndexedDbQueryBuilder<any>, options: {
1983
1998
  readonly tables: NonEmptyReadonlyArray<any>
1984
1999
  readonly mode: globalThis.IDBTransactionMode
@@ -1987,7 +2002,11 @@ const QueryBuilderProto: Omit<
1987
2002
  return (effect) =>
1988
2003
  Effect.suspend(() => {
1989
2004
  const transaction = this.database.current.transaction(options.tables, options.mode, options)
1990
- return Effect.provideService(effect, IndexedDbTransaction, transaction)
2005
+ return Effect.provideService(effect, IndexedDbTransaction, transaction).pipe(
2006
+ Effect.onExit((exit) =>
2007
+ exit._tag === "Success" ? awaitTransaction(transaction) : abortTransaction(transaction)
2008
+ )
2009
+ )
1991
2010
  }).pipe(
1992
2011
  // To prevent async gaps between transaction queries
1993
2012
  Effect.provideService(References.PreventSchedulerYield, true)
@@ -1995,6 +2014,30 @@ const QueryBuilderProto: Omit<
1995
2014
  }
1996
2015
  }
1997
2016
 
2017
+ const abortTransaction = (transaction: globalThis.IDBTransaction) =>
2018
+ Effect.try({
2019
+ try: () => transaction.abort(),
2020
+ catch: () => undefined
2021
+ }).pipe(Effect.ignore)
2022
+
2023
+ const awaitTransaction = (transaction: globalThis.IDBTransaction) =>
2024
+ Effect.callback<void, IndexedDbQueryError>((resume) => {
2025
+ transaction.oncomplete = () => {
2026
+ resume(Effect.void)
2027
+ }
2028
+ transaction.onabort = () => {
2029
+ resume(
2030
+ Effect.fail(
2031
+ new IndexedDbQueryError({
2032
+ reason: "TransactionError",
2033
+ cause: transaction.error
2034
+ })
2035
+ )
2036
+ )
2037
+ }
2038
+ return abortTransaction(transaction)
2039
+ })
2040
+
1998
2041
  /**
1999
2042
  * Creates an `IndexedDbQueryBuilder` from an open database reference, key-range constructor, table map, and reactivity service.
2000
2043
  *
@@ -23,7 +23,7 @@ const TypeId = "~@effect/platform-browser/IndexedDbTable"
23
23
  /**
24
24
  * Typed IndexedDB table definition containing its name, schema, key path, indexes, auto-increment setting, and transaction durability.
25
25
  *
26
- * @category interface
26
+ * @category models
27
27
  * @since 4.0.0
28
28
  */
29
29
  export interface IndexedDbTable<
@@ -94,14 +94,14 @@ export type AnyWithProps = IndexedDbTable<
94
94
  /**
95
95
  * Extracts the table name type from an `IndexedDbTable`.
96
96
  *
97
- * @category models
97
+ * @category utility types
98
98
  * @since 4.0.0
99
99
  */
100
100
  export type TableName<Table extends Any> = Table["tableName"]
101
101
  /**
102
102
  * Extracts the key-path type from an `IndexedDbTable`.
103
103
  *
104
- * @category models
104
+ * @category utility types
105
105
  * @since 4.0.0
106
106
  */
107
107
  export type KeyPath<Table extends Any> = Table["keyPath"]
@@ -109,7 +109,7 @@ export type KeyPath<Table extends Any> = Table["keyPath"]
109
109
  /**
110
110
  * Extracts the auto-increment flag type from an `IndexedDbTable`.
111
111
  *
112
- * @category models
112
+ * @category utility types
113
113
  * @since 4.0.0
114
114
  */
115
115
  export type AutoIncrement<Table extends Any> = Table["autoIncrement"]
@@ -117,14 +117,14 @@ export type AutoIncrement<Table extends Any> = Table["autoIncrement"]
117
117
  /**
118
118
  * Extracts the schema type from an `IndexedDbTable`.
119
119
  *
120
- * @category models
120
+ * @category utility types
121
121
  * @since 4.0.0
122
122
  */
123
123
  export type TableSchema<Table extends Any> = Table["tableSchema"]
124
124
  /**
125
125
  * Extracts the decoding or encoding service requirements needed by an `IndexedDbTable` schema.
126
126
  *
127
- * @category models
127
+ * @category utility types
128
128
  * @since 4.0.0
129
129
  */
130
130
  export type Context<Table extends Any> =
@@ -134,7 +134,7 @@ export type Context<Table extends Any> =
134
134
  /**
135
135
  * Extracts the encoded row type from an `IndexedDbTable` schema.
136
136
  *
137
- * @category models
137
+ * @category utility types
138
138
  * @since 4.0.0
139
139
  */
140
140
  export type Encoded<Table extends Any> = Table["tableSchema"]["Encoded"]
@@ -142,7 +142,7 @@ export type Encoded<Table extends Any> = Table["tableSchema"]["Encoded"]
142
142
  /**
143
143
  * Extracts the index definition map from an `IndexedDbTable`.
144
144
  *
145
- * @category models
145
+ * @category utility types
146
146
  * @since 4.0.0
147
147
  */
148
148
  export type Indexes<Table extends Any> = Table["indexes"]
@@ -150,7 +150,7 @@ export type Indexes<Table extends Any> = Table["indexes"]
150
150
  /**
151
151
  * Selects the table with the given name from a union of `IndexedDbTable` types.
152
152
  *
153
- * @category models
153
+ * @category utility types
154
154
  * @since 4.0.0
155
155
  */
156
156
  export type WithName<Table extends Any, TableName extends string> = Extract<
@@ -27,7 +27,7 @@ const TypeId = "~@effect/platform-browser/IndexedDbVersion"
27
27
  /**
28
28
  * Typed IndexedDB version definition containing the tables available in that schema version.
29
29
  *
30
- * @category interface
30
+ * @category models
31
31
  * @since 4.0.0
32
32
  */
33
33
  export interface IndexedDbVersion<
@@ -59,7 +59,7 @@ export type AnyWithProps = IndexedDbVersion<IndexedDbTable.AnyWithProps>
59
59
  /**
60
60
  * Extracts the table union from an `IndexedDbVersion`.
61
61
  *
62
- * @category models
62
+ * @category utility types
63
63
  * @since 4.0.0
64
64
  */
65
65
  export type Tables<Db extends Any> = Db extends IndexedDbVersion<infer _Tables> ? _Tables : never
@@ -67,7 +67,7 @@ export type Tables<Db extends Any> = Db extends IndexedDbVersion<infer _Tables>
67
67
  /**
68
68
  * Selects a table by name from an `IndexedDbVersion`.
69
69
  *
70
- * @category models
70
+ * @category utility types
71
71
  * @since 4.0.0
72
72
  */
73
73
  export type TableWithName<
@@ -78,7 +78,7 @@ export type TableWithName<
78
78
  /**
79
79
  * Extracts the schema for a named table within an `IndexedDbVersion`.
80
80
  *
81
- * @category models
81
+ * @category utility types
82
82
  * @since 4.0.0
83
83
  */
84
84
  export type SchemaWithName<
@@ -21,7 +21,7 @@ const ErrorTypeId = "~@effect/platform-browser/Permissions/PermissionsError"
21
21
  * Wrapper on the Permission API (`navigator.permissions`) with methods for
22
22
  * querying status of permissions.
23
23
  *
24
- * @category models
24
+ * @category services
25
25
  * @since 4.0.0
26
26
  */
27
27
  export interface Permissions {