tinybase 6.2.1 → 6.3.0

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 (183) hide show
  1. package/@types/omni/index.d.ts +1 -0
  2. package/@types/omni/with-schemas/index.d.ts +1 -0
  3. package/@types/persisters/index.d.ts +4 -2
  4. package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +348 -0
  5. package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +381 -0
  6. package/@types/persisters/with-schemas/index.d.ts +4 -2
  7. package/@types/queries/index.d.ts +1 -1
  8. package/@types/queries/with-schemas/index.d.ts +1 -1
  9. package/LICENSE +1 -1
  10. package/min/checkpoints/index.js +1 -1
  11. package/min/checkpoints/index.js.gz +0 -0
  12. package/min/checkpoints/with-schemas/index.js +1 -1
  13. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  14. package/min/common/index.js +1 -1
  15. package/min/common/index.js.gz +0 -0
  16. package/min/common/with-schemas/index.js +1 -1
  17. package/min/common/with-schemas/index.js.gz +0 -0
  18. package/min/index.js +1 -1
  19. package/min/index.js.gz +0 -0
  20. package/min/indexes/index.js +1 -1
  21. package/min/indexes/index.js.gz +0 -0
  22. package/min/indexes/with-schemas/index.js +1 -1
  23. package/min/indexes/with-schemas/index.js.gz +0 -0
  24. package/min/mergeable-store/index.js +1 -1
  25. package/min/mergeable-store/index.js.gz +0 -0
  26. package/min/mergeable-store/with-schemas/index.js +1 -1
  27. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  28. package/min/metrics/index.js +1 -1
  29. package/min/metrics/index.js.gz +0 -0
  30. package/min/metrics/with-schemas/index.js +1 -1
  31. package/min/metrics/with-schemas/index.js.gz +0 -0
  32. package/min/omni/index.js +1 -1
  33. package/min/omni/index.js.gz +0 -0
  34. package/min/omni/with-schemas/index.js +1 -1
  35. package/min/omni/with-schemas/index.js.gz +0 -0
  36. package/min/persisters/index.js +1 -1
  37. package/min/persisters/index.js.gz +0 -0
  38. package/min/persisters/persister-automerge/index.js +1 -1
  39. package/min/persisters/persister-automerge/index.js.gz +0 -0
  40. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  41. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  42. package/min/persisters/persister-browser/index.js +1 -1
  43. package/min/persisters/persister-browser/index.js.gz +0 -0
  44. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  45. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  46. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  47. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  48. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  49. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  50. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -0
  51. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  52. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -0
  53. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  54. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  55. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  56. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  57. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  58. package/min/persisters/persister-electric-sql/index.js +1 -1
  59. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  60. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  61. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  62. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  63. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  64. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  65. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  66. package/min/persisters/persister-file/index.js +1 -1
  67. package/min/persisters/persister-file/index.js.gz +0 -0
  68. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  69. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  70. package/min/persisters/persister-indexed-db/index.js +1 -1
  71. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  72. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  73. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  74. package/min/persisters/persister-libsql/index.js +1 -1
  75. package/min/persisters/persister-libsql/index.js.gz +0 -0
  76. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  77. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  78. package/min/persisters/persister-partykit-client/index.js +1 -1
  79. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  80. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  81. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  82. package/min/persisters/persister-partykit-server/index.js +1 -1
  83. package/min/persisters/persister-partykit-server/index.js.gz +0 -0
  84. package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
  85. package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
  86. package/min/persisters/persister-pglite/index.js +1 -1
  87. package/min/persisters/persister-pglite/index.js.gz +0 -0
  88. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  89. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  90. package/min/persisters/persister-postgres/index.js +1 -1
  91. package/min/persisters/persister-postgres/index.js.gz +0 -0
  92. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  93. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  94. package/min/persisters/persister-powersync/index.js +1 -1
  95. package/min/persisters/persister-powersync/index.js.gz +0 -0
  96. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  97. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  98. package/min/persisters/persister-remote/index.js +1 -1
  99. package/min/persisters/persister-remote/index.js.gz +0 -0
  100. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  101. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  102. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  103. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  104. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  105. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  106. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  107. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  108. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  109. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  110. package/min/persisters/persister-sqlite3/index.js +1 -1
  111. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  112. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  113. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  114. package/min/persisters/persister-yjs/index.js +1 -1
  115. package/min/persisters/persister-yjs/index.js.gz +0 -0
  116. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  117. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  118. package/min/persisters/with-schemas/index.js +1 -1
  119. package/min/persisters/with-schemas/index.js.gz +0 -0
  120. package/min/queries/index.js +1 -1
  121. package/min/queries/index.js.gz +0 -0
  122. package/min/queries/with-schemas/index.js +1 -1
  123. package/min/queries/with-schemas/index.js.gz +0 -0
  124. package/min/relationships/index.js +1 -1
  125. package/min/relationships/index.js.gz +0 -0
  126. package/min/relationships/with-schemas/index.js +1 -1
  127. package/min/relationships/with-schemas/index.js.gz +0 -0
  128. package/min/store/index.js +1 -1
  129. package/min/store/index.js.gz +0 -0
  130. package/min/store/with-schemas/index.js +1 -1
  131. package/min/store/with-schemas/index.js.gz +0 -0
  132. package/min/synchronizers/index.js +1 -1
  133. package/min/synchronizers/index.js.gz +0 -0
  134. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  135. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  136. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  137. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  138. package/min/synchronizers/synchronizer-local/index.js +1 -1
  139. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  140. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  141. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  142. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  143. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  144. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  145. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  146. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  147. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  148. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  149. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  150. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  151. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  152. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  153. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  154. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  155. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  156. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  157. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  158. package/min/synchronizers/with-schemas/index.js +1 -1
  159. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  160. package/min/ui-react/index.js +1 -1
  161. package/min/ui-react/index.js.gz +0 -0
  162. package/min/ui-react/with-schemas/index.js +1 -1
  163. package/min/ui-react/with-schemas/index.js.gz +0 -0
  164. package/min/ui-react-dom/index.js +1 -1
  165. package/min/ui-react-dom/index.js.gz +0 -0
  166. package/min/ui-react-dom/with-schemas/index.js +1 -1
  167. package/min/ui-react-dom/with-schemas/index.js.gz +0 -0
  168. package/min/ui-react-inspector/index.js +1 -1
  169. package/min/ui-react-inspector/index.js.gz +0 -0
  170. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  171. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  172. package/min/with-schemas/index.js +1 -1
  173. package/min/with-schemas/index.js.gz +0 -0
  174. package/omni/index.js +4 -1
  175. package/omni/with-schemas/index.js +4 -1
  176. package/package.json +43 -7
  177. package/persisters/persister-browser/index.js +4 -1
  178. package/persisters/persister-browser/with-schemas/index.js +4 -1
  179. package/persisters/persister-durable-object-sql-storage/index.js +1391 -0
  180. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1391 -0
  181. package/readme.md +2 -2
  182. package/ui-react-inspector/index.js +4 -1
  183. package/ui-react-inspector/with-schemas/index.js +4 -1
@@ -0,0 +1,381 @@
1
+ /**
2
+ * The persister-durable-object-sql-storage module of the TinyBase project lets
3
+ * you save and load Store data to and from Cloudflare Durable Object SQLite
4
+ * storage (in an appropriate environment).
5
+ *
6
+ * Cloudflare's SQLite storage backend for Durable Objects offers significantly
7
+ * better pricing compared to the key-value storage backend. The SQLite storage
8
+ * backend is Cloudflare's recommended storage option for new Durable Object
9
+ * namespaces.
10
+ *
11
+ * **Important:** Before using this persister, you must configure your Durable
12
+ * Object class to use SQLite storage by adding a migration to your
13
+ * `wrangler.toml` or `wrangler.json` configuration file. Use
14
+ * `new_sqlite_classes` in your migration configuration to enable SQLite storage
15
+ * for your Durable Object class.
16
+ *
17
+ * See [Cloudflare's
18
+ * documentation](https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/)
19
+ * for more details.
20
+ * @see Cloudflare Durable Objects guide
21
+ * @see Persistence guides
22
+ * @packageDocumentation
23
+ * @module persister-durable-object-sql-storage
24
+ * @since v6.3.0
25
+ */
26
+ import type {MergeableStore} from '../../../mergeable-store/with-schemas/index.d.ts';
27
+ import type {
28
+ OptionalSchemas,
29
+ Store,
30
+ } from '../../../store/with-schemas/index.d.ts';
31
+ import type {
32
+ DatabasePersisterConfig,
33
+ Persister,
34
+ Persists,
35
+ } from '../../with-schemas/index.d.ts';
36
+
37
+ /**
38
+ * The DpcFragmented type represents the configuration for fragmented
39
+ * persistence mode in a DurableObjectSqlStoragePersister.
40
+ *
41
+ * This mode stores each table, row, cell, and value as separate database rows,
42
+ * avoiding Cloudflare's 2MB row limit that can be hit with large stores in JSON
43
+ * mode. While this creates more database writes, it provides better scalability
44
+ * for larger datasets.
45
+ * @example
46
+ * This example shows how to configure a DurableObjectSqlStoragePersister to use
47
+ * fragmented mode with a custom storage prefix.
48
+ *
49
+ * ```js yolo
50
+ * import {createMergeableStore} from 'tinybase';
51
+ * import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
52
+ * import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
53
+ *
54
+ * const config = {
55
+ * mode: 'fragmented',
56
+ * storagePrefix: 'my_app_',
57
+ * };
58
+ *
59
+ * export class MyDurableObject extends WsServerDurableObject {
60
+ * createPersister() {
61
+ * const store = createMergeableStore();
62
+ * const persister = createDurableObjectSqlStoragePersister(
63
+ * store,
64
+ * this.ctx.storage.sql,
65
+ * config,
66
+ * );
67
+ * return persister;
68
+ * }
69
+ * }
70
+ * ```
71
+ * @category Configuration
72
+ * @since v6.3.0
73
+ */
74
+ export type DpcFragmented = {
75
+ /**
76
+ * The mode property must be set to 'fragmented' to enable fragmented
77
+ * persistence mode.
78
+ * @category Configuration
79
+ * @since v6.3.0
80
+ */
81
+ mode: 'fragmented';
82
+ /**
83
+ * The storagePrefix property lets you specify an optional prefix for the
84
+ * database table names used in fragmented mode.
85
+ *
86
+ * This is useful when you have multiple stores or applications sharing the
87
+ * same Durable Object SQL storage and want to avoid table name conflicts.
88
+ *
89
+ * The prefix will be sanitized to only include alphanumeric characters and
90
+ * underscores. For example, a prefix of 'my-app!' becomes 'my_app_'.
91
+ * @example
92
+ * This example shows a configuration using the storagePrefix setting. With a
93
+ * `storagePrefix` of 'user_data_', it creates `user_data_tinybase_tables` and
94
+ * `user_data_tinybase_values` tables.
95
+ * ```json
96
+ * {
97
+ * mode: 'fragmented',
98
+ * storagePrefix: 'user_data_',
99
+ * };
100
+ * ```
101
+ * @category Configuration
102
+ * @since v6.3.0
103
+ */
104
+ storagePrefix?: string;
105
+ };
106
+
107
+ /**
108
+ * The DurableObjectSqlDatabasePersisterConfig type represents the union of all
109
+ * possible configuration types for a DurableObjectSqlStoragePersister.
110
+ *
111
+ * This has schema-based typing. The following is a simplified representation:
112
+ *
113
+ * ```ts override
114
+ * DpcJson | DpcFragmented;
115
+ * ```
116
+ *
117
+ * This allows the persister to support multiple persistence modes.
118
+ * - JSON mode (via DpcJson): Stores the entire Store as JSON in a single row.
119
+ * - Fragmented mode (via DpcFragmented): Stores each piece of data as separate
120
+ * rows.
121
+ * @example
122
+ * These examples show some different configuration options.
123
+ * ```json
124
+ * // JSON mode (default)
125
+ * {
126
+ * mode: 'json',
127
+ * storeTableName: 'my_store',
128
+ * };
129
+ *
130
+ * // Fragmented mode
131
+ * {
132
+ * mode: 'fragmented',
133
+ * storagePrefix: 'app_',
134
+ * };
135
+ * ```
136
+ * @category Configuration
137
+ * @since v6.3.0
138
+ */
139
+ export type DurableObjectSqlDatabasePersisterConfig<
140
+ Schemas extends OptionalSchemas,
141
+ > = DatabasePersisterConfig<Schemas> | DpcFragmented;
142
+
143
+ /**
144
+ * The DurableObjectSqlStoragePersister interface represents a Persister that
145
+ * lets you save and load Store data to and from Cloudflare Durable Object SQL
146
+ * storage.
147
+ *
148
+ * You should use the createDurableObjectSqlStoragePersister function to create
149
+ * a DurableObjectSqlStoragePersister object, most likely within the
150
+ * createPersister method of a WsServerDurableObject.
151
+ *
152
+ * It is a minor extension to the Persister interface and simply provides an
153
+ * extra getSqlStorage method for accessing a reference to the SQL storage that
154
+ * the Store is being persisted to.
155
+ * @category Persister
156
+ * @since v6.3.0
157
+ */
158
+ export interface DurableObjectSqlStoragePersister<
159
+ Schemas extends OptionalSchemas,
160
+ > extends Persister<Schemas, Persists.MergeableStoreOnly> {
161
+ /**
162
+ * The getSqlStorage method returns a reference to the SQL storage that the
163
+ * Store is being persisted to.
164
+ * @returns The reference to the SQL storage.
165
+ * @example
166
+ * This example creates a Persister object against a newly-created Store
167
+ * (within the createPersister method of a WsServerDurableObject instance) and
168
+ * then gets the SQL storage reference back out again.
169
+ *
170
+ * ```js yolo
171
+ * import {createMergeableStore} from 'tinybase';
172
+ * import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
173
+ * import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
174
+ *
175
+ * export class MyDurableObject extends WsServerDurableObject {
176
+ * createPersister() {
177
+ * const store = createMergeableStore();
178
+ * const persister = createDurableObjectSqlStoragePersister(
179
+ * store,
180
+ * this.ctx.storage.sql,
181
+ * );
182
+ * console.log(persister.getSqlStorage() == this.ctx.storage.sql);
183
+ * // -> true
184
+ *
185
+ * return persister;
186
+ * }
187
+ * }
188
+ * ```
189
+ * @category Getter
190
+ * @since v6.3.0
191
+ */
192
+ getSqlStorage(): SqlStorage;
193
+ }
194
+
195
+ /**
196
+ * The createDurableObjectSqlStoragePersister function creates a
197
+ * DurableObjectSqlStoragePersister object that can persist the Store to and
198
+ * from Cloudflare Durable Object SQLite storage.
199
+ *
200
+ * This has schema-based typing. The following is a simplified representation:
201
+ *
202
+ * ```ts override
203
+ * createDurableObjectSqlStoragePersister(
204
+ * store: MergeableStore,
205
+ * sqlStorage: SqlStorage,
206
+ * configOrStoreTableName?: DurableObjectSqlDatabasePersisterConfig | string,
207
+ * onSqlCommand?: (sql: string, params?: any[]) => void,
208
+ * onIgnoredError?: (error: any) => void,
209
+ * ): DurableObjectSqlStoragePersister;
210
+ * ```
211
+ *
212
+ * You will mostly use this within the createPersister method of a
213
+ * WsServerDurableObject.
214
+ *
215
+ * This persister uses Cloudflare's SQLite storage backend, which provides
216
+ * better pricing and performance compared to the legacy Key-value storage
217
+ * backend.
218
+ *
219
+ * **Important Prerequisites:** Before using this persister, you must configure
220
+ * your Durable Object class to use SQLite storage by adding a migration to your
221
+ * Wrangler configuration file. In your `wrangler.toml`, add the following.
222
+ * ```toml
223
+ * [[migrations]]
224
+ * tag = "v1"
225
+ * new_sqlite_classes = ["YourDurableObjectClass"]
226
+ * ```
227
+ *
228
+ * Or in your `wrangler.json`, add:
229
+ *
230
+ * ```json
231
+ * {
232
+ * "migrations": [
233
+ * {
234
+ * "tag": "v1",
235
+ * "new_sqlite_classes": ["YourDurableObjectClass"]
236
+ * }
237
+ * ]
238
+ * }
239
+ * ```
240
+ *
241
+ * For more details on Durable Object migrations, see the [Cloudflare
242
+ * documentation](https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/).
243
+ *
244
+ * A database Persister uses one of two modes: either a JSON serialization of
245
+ * the whole Store stored in a single row of a table (the default), a fragmented
246
+ * mode that stores each piece of data separately to avoid Cloudflare's 2MB row
247
+ * limit.
248
+ *
249
+ * - **JSON Mode (Default)**: Stores the entire Store as JSON in a single
250
+ * database row. This is efficient for smaller stores but may hit Cloudflare's
251
+ * 2MB row limit for very large stores and uses fewer database writes.
252
+ *
253
+ * - **Fragmented Mode**: Stores each table, row, cell, and value as separate
254
+ * database rows. Use this mode if you're concerned about hitting Cloudflare's
255
+ * 2MB row limit with large stores in JSON mode. This mode creates more
256
+ * database writes but avoids row size limitations.
257
+ *
258
+ * The third argument is a DatabasePersisterConfig object that configures which
259
+ * of those modes to use, and settings for each. If the third argument is simply
260
+ * a string, it is used as the `storeTableName` property of the JSON
261
+ * serialization. If it is the string 'fragmented', it enables fragmented mode.
262
+ *
263
+ * See the documentation for the DpcJson, DpcFragmented, and DpcTabular types
264
+ * for more information on how all of those modes can be configured.
265
+ *
266
+ * As well as providing a reference to the Store or MergeableStore to persist,
267
+ * you must provide a `sqlStorage` parameter which identifies the Durable Object
268
+ * SQLite storage to persist it to.
269
+ * @param store The Store or MergeableStore to persist.
270
+ * @param sqlStorage The Durable Object SQL storage to persist the Store to.
271
+ * @param configOrStoreTableName A DatabasePersisterConfig to configure the
272
+ * persistence mode (or a string to set the `storeTableName` property of the
273
+ * JSON serialization).
274
+ * @param onSqlCommand An optional handler called every time the Persister
275
+ * executes a SQL command or query. This is suitable for logging persistence
276
+ * behavior in a development environment.
277
+ * @param onIgnoredError An optional handler for the errors that the Persister
278
+ * would otherwise ignore when trying to save or load data. This is suitable for
279
+ * debugging persistence issues in a development environment.
280
+ * @returns A reference to the new DurableObjectSqlStoragePersister object.
281
+ * @example
282
+ * This example creates a DurableObjectSqlStoragePersister object and persists
283
+ * the Store to Durable Object SQLite storage as a JSON serialization into the
284
+ * default `tinybase` table. It uses this within the createPersister method of a
285
+ * WsServerDurableObject instance.
286
+ *
287
+ * ```js yolo
288
+ * import {createMergeableStore} from 'tinybase';
289
+ * import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
290
+ * import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
291
+ *
292
+ * export class MyDurableObject extends WsServerDurableObject {
293
+ * createPersister() {
294
+ * const store = createMergeableStore();
295
+ * const persister = createDurableObjectSqlStoragePersister(
296
+ * store,
297
+ * this.ctx.storage.sql,
298
+ * );
299
+ * return persister;
300
+ * }
301
+ * }
302
+ * ```
303
+ * @example
304
+ * This example creates a DurableObjectSqlStoragePersister object with a custom
305
+ * table name and SQL command logging for debugging.
306
+ *
307
+ * ```js yolo
308
+ * import {createMergeableStore} from 'tinybase';
309
+ * import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
310
+ * import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
311
+ *
312
+ * export class MyDurableObject extends WsServerDurableObject {
313
+ * createPersister() {
314
+ * const store = createMergeableStore();
315
+ * const persister = createDurableObjectSqlStoragePersister(
316
+ * store,
317
+ * this.ctx.storage.sql,
318
+ * 'my_app_store',
319
+ * (sql, params) => console.log('SQL:', sql, params),
320
+ * (error) => console.error('Persistence error:', error),
321
+ * );
322
+ * return persister;
323
+ * }
324
+ * }
325
+ * ```
326
+ * @example
327
+ * This example creates a DurableObjectSqlStoragePersister object using
328
+ * fragmented mode to avoid Cloudflare's 2MB row limit for large stores.
329
+ *
330
+ * ```js yolo
331
+ * import {createMergeableStore} from 'tinybase';
332
+ * import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
333
+ * import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
334
+ *
335
+ * export class MyDurableObject extends WsServerDurableObject {
336
+ * createPersister() {
337
+ * const store = createMergeableStore();
338
+ * const persister = createDurableObjectSqlStoragePersister(
339
+ * store,
340
+ * this.ctx.storage.sql,
341
+ * {mode: 'fragmented'},
342
+ * );
343
+ * return persister;
344
+ * }
345
+ * }
346
+ * ```
347
+ * @example
348
+ * This example creates a DurableObjectSqlStoragePersister object using
349
+ * fragmented mode with a custom storage prefix.
350
+ *
351
+ * ```js yolo
352
+ * import {createMergeableStore} from 'tinybase';
353
+ * import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
354
+ * import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
355
+ *
356
+ * export class MyDurableObject extends WsServerDurableObject {
357
+ * createPersister() {
358
+ * const store = createMergeableStore();
359
+ * const persister = createDurableObjectSqlStoragePersister(
360
+ * store,
361
+ * this.ctx.storage.sql,
362
+ * {mode: 'fragmented', storagePrefix: 'my_app_'},
363
+ * );
364
+ * return persister;
365
+ * }
366
+ * }
367
+ * ```
368
+ * @category Creation
369
+ * @since v6.3.0
370
+ */
371
+ export function createDurableObjectSqlStoragePersister<
372
+ Schemas extends OptionalSchemas,
373
+ >(
374
+ store: Store<Schemas> | MergeableStore<Schemas>,
375
+ sqlStorage: SqlStorage,
376
+ configOrStoreTableName?:
377
+ | DurableObjectSqlDatabasePersisterConfig<Schemas>
378
+ | string,
379
+ onSqlCommand?: (sql: string, params?: any[]) => void,
380
+ onIgnoredError?: (error: any) => void,
381
+ ): DurableObjectSqlStoragePersister<Schemas>;
@@ -6,8 +6,8 @@
6
6
  * Many entry points are provided (in separately installed modules), each of
7
7
  * which returns different types of Persister that can load and save a Store.
8
8
  * Between them, these allow you to store your TinyBase data locally, remotely,
9
- * to SQLite and PostgreSQL databases, and across synchronization boundaries
10
- * with CRDT frameworks.
9
+ * to a Durable Object, to SQLite and PostgreSQL databases, and across
10
+ * synchronization boundaries with CRDT frameworks.
11
11
  *
12
12
  * |Persister|Storage|Store|MergeableStore
13
13
  * |-|-|-|-|
@@ -16,6 +16,8 @@
16
16
  * |FilePersister|Local file (where possible)|Yes|Yes
17
17
  * |IndexedDbPersister|Browser IndexedDB|Yes|No
18
18
  * |RemotePersister|Remote server|Yes|No
19
+ * |DurableObjectStoragePersister|Cloudflare Durable Object (KV)|No|Yes
20
+ * |DurableObjectSqlStoragePersister|Cloudflare Durable Object (SQLite)|No|Yes
19
21
  * |Sqlite3Persister|SQLite in Node, via [sqlite3](https://github.com/TryGhost/node-sqlite3)|Yes|Yes*
20
22
  * |SqliteBunPersister| SQLite in Bun, via [bun:sqlite](https://bun.sh/docs/api/sqlite)|Yes|Yes*
21
23
  * |SqliteWasmPersister|SQLite in a browser, via [sqlite-wasm](https://github.com/tomayac/sqlite-wasm)|Yes|Yes*
@@ -1331,7 +1331,7 @@ export type Where = {
1331
1331
  * If you provide a Group for every Select, the result will be a single Row with
1332
1332
  * every Cell having been aggregated. If you provide a Group for only one, or
1333
1333
  * some, of the Select clauses, the _others_ will be automatically used as
1334
- * dimensional values (analogous to the 'group by` semantics in SQL), within
1334
+ * dimensional values (analogous to the `group by` semantics in SQL), within
1335
1335
  * which the aggregations of Group Cells will be performed.
1336
1336
  *
1337
1337
  * You can join the same underlying Cell multiple times, but in that case you
@@ -1518,7 +1518,7 @@ export type Where<
1518
1518
  * If you provide a Group for every Select, the result will be a single Row with
1519
1519
  * every Cell having been aggregated. If you provide a Group for only one, or
1520
1520
  * some, of the Select clauses, the _others_ will be automatically used as
1521
- * dimensional values (analogous to the 'group by` semantics in SQL), within
1521
+ * dimensional values (analogous to the `group by` semantics in SQL), within
1522
1522
  * which the aggregations of Group Cells will be performed.
1523
1523
  *
1524
1524
  * You can join the same underlying Cell multiple times, but in that case you
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) James Pearce, 2021-
3
+ Copyright (c) James Pearce, 2021 -
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1 +1 @@
1
- const e=e=>null==e,t=(t,n,r)=>e(t)?r?.():n(t),n=e=>e.length,r=(e,t)=>e.includes(t),s=(e,t)=>e.forEach(t),o=e=>0==n(e),l=(e,...t)=>e.push(...t),c=e=>e.pop(),i=e=>e.shift(),a=e=>e?.size??0,d=(u=a,e=>{return t=(e,t)=>e+u(t),g(e).reduce(t,0);var t});var u;const h=(e,t)=>e?.has(t)??!1,p=t=>e(t)||0==a(t),g=e=>[...e?.values()??[]],k=(e,t)=>e?.forEach(t),C=(e,t)=>e?.delete(t),f=Object.freeze,v=e=>new Map(e),L=(e,t)=>e?.get(t),w=(t,n,r)=>e(r)?(C(t,n),t):t?.set(n,r),S=(e,t,n,r)=>(h(e,t)?r?.(L(e,t)):w(e,t,n()),L(e,t)),y=(e,r,s,o,l=0)=>t((s?S:L)(e,r[l],l>n(r)-2?s:v),(t=>{if(l>n(r)-2)return o?.(t)&&w(e,r[l]),t;const c=y(t,r,s,o,l+1);return p(t)&&w(e,r[l]),c})),z=t=>new Set(Array.isArray(t)||e(t)?t:[t]),E=/^\d+$/,I=(()=>{const a=new WeakMap;return u=>{a.has(u)||a.set(u,(a=>{let u,g,I,V=100,A=v(),F=v(),M=1;const _=v(),b=v(),[j,x,B]=(()=>{let r;const[o,c]=(()=>{const e=[];let t=0;return[n=>(n?i(e):null)??""+t++,t=>{E.test(t)&&n(e)<1e3&&l(e,t)}]})(),a=v();return[(e,t,n,s=[],l=()=>[])=>{r??=ee;const c=o(1);var i,d;return w(a,c,[e,t,n,s,l]),i=y(t,n??[""],z),d=c,i?.add(d),c},(e,t,...o)=>s(((e,t=[""])=>{const r=[],o=(e,c)=>c==n(t)?l(r,e):null===t[c]?k(e,(e=>o(e,c+1))):s([t[c],null],(t=>o(L(e,t),c+1)));return o(e,0),r})(e,t),(e=>k(e,(e=>L(a,e)[0](r,...t??[],...o))))),e=>t(L(a,e),(([,t,n])=>(y(t,n??[""],void 0,(t=>(C(t,e),p(t)?1:0))),w(a,e),c(e),n))),o=>t(L(a,o),(([t,,o=[],l,c])=>{const i=(...a)=>{const d=n(a);d==n(o)?t(r,...a,...c(a)):e(o[d])?s(l[d]?.(...a)??[],(e=>i(...a,e))):i(...a,o[d])};i()}))]})(),O=v(),T=v(),W=[],$=[],m=(t,n)=>{M=0,a.transaction((()=>{const[r,s]=L(O,n);k(r,((n,r)=>k(n,((n,s)=>k(n,((n,o)=>((t,n,r,s,o)=>e(o)?t.delCell(n,r,s,!0):t.setCell(n,r,s,o))(a,r,s,o,n[t]))))))),k(s,((n,r)=>((t,n,r)=>e(r)?t.delValue(n):t.setValue(n,r))(a,r,n[t])))})),M=1},q=e=>{w(O,e),w(T,e),x(b,[e])},D=(e,t)=>s(((e,t)=>e.splice(0,t))(e,t??n(e)),q),G=()=>D(W,n(W)-V),H=()=>t(u,(()=>{l(W,u),G(),D($),u=void 0,I=1})),J=()=>{u=c(W),I=1};let K,N;const P=(t="")=>(e(u)&&(u=""+g++,w(O,u,[A,F]),Y(u,t),A=v(),F=v(),I=1),u),Q=()=>{o(W)||(((e,...t)=>{e.unshift(...t)})($,P()),m(0,u),u=c(W),I=1)},R=()=>{o($)||(l(W,u),u=i($),m(1,u),I=1)},U=()=>{I&&(x(_),I=0)},X=e=>{const t=P(e);return U(),t},Y=(e,t)=>(Z(e)&&L(T,e)!==t&&(w(T,e,t),x(b,[e])),ee),Z=e=>h(O,e),ee={setSize:e=>(V=e,G(),ee),addCheckpoint:X,setCheckpoint:Y,getStore:()=>a,getCheckpointIds:()=>[[...W],u,[...$]],forEachCheckpoint:e=>{return t=e,k(T,((e,n)=>t(n,e)));var t},hasCheckpoint:Z,getCheckpoint:e=>L(T,e),goBackward:()=>(Q(),U(),ee),goForward:()=>(R(),U(),ee),goTo:t=>{const n=r(W,t)?Q:r($,t)?R:null;for(;!e(n)&&t!=u;)n();return U(),ee},addCheckpointIdsListener:e=>j(e,_),addCheckpointListener:(e,t)=>j(t,b,[e]),delListener:e=>(B(e),ee),clear:()=>(D(W),D($),e(u)||q(u),u=void 0,g=0,X(),ee),clearForward:()=>(o($)||(D($),x(_)),ee),destroy:()=>{a.delListener(K),a.delListener(N)},getListenerStats:()=>({checkpointIds:d(_),checkpoint:d(b)}),_registerListeners:()=>{K=a.addCellListener(null,null,null,((e,t,n,r,s,o)=>{if(M){H();const e=S(A,t,v),l=S(e,n,v),c=S(l,r,(()=>[o,void 0]));c[1]=s,c[0]===s&&p(w(l,r))&&p(w(e,n))&&p(w(A,t))&&J(),U()}})),N=a.addValueListener(null,((e,t,n,r)=>{if(M){H();const e=S(F,t,(()=>[r,void 0]));e[1]=n,e[0]===n&&p(w(F,t))&&J(),U()}}))}};return f(ee.clear())})(u));const g=a.get(u);return g._registerListeners(),g}})();export{I as createCheckpoints};
1
+ const e=e=>null==e,t=(t,n,r)=>e(t)?r?.():n(t),n=e=>e.length,r=(e,t)=>e.includes(t),s=(e,t)=>e.forEach(t),o=e=>0==n(e),l=(e,...t)=>e.push(...t),c=e=>e.pop(),i=e=>e.shift(),a=e=>e?.size??0,d=(u=a,e=>{return t=(e,t)=>e+u(t),g(e).reduce(t,0);var t});var u;const h=(e,t)=>e?.has(t)??!1,p=t=>e(t)||0==a(t),g=e=>[...e?.values()??[]],k=(e,t)=>e?.forEach(t),C=(e,t)=>e?.delete(t),f=Object.freeze,v=e=>new Map(e),L=(e,t)=>e?.get(t),w=(t,n,r)=>e(r)?(C(t,n),t):t?.set(n,r),S=(e,t,n,r)=>(h(e,t)?r?.(L(e,t)):w(e,t,n()),L(e,t)),y=(e,r,s,o,l=0)=>t((s?S:L)(e,r[l],l>n(r)-2?s:v),t=>{if(l>n(r)-2)return o?.(t)&&w(e,r[l]),t;const c=y(t,r,s,o,l+1);return p(t)&&w(e,r[l]),c}),z=t=>new Set(Array.isArray(t)||e(t)?t:[t]),E=/^\d+$/,I=(()=>{const a=new WeakMap;return u=>{a.has(u)||a.set(u,(a=>{let u,g,I,V=100,A=v(),F=v(),M=1;const _=v(),b=v(),[j,x,B]=(()=>{let r;const[o,c]=(()=>{const e=[];let t=0;return[n=>(n?i(e):null)??""+t++,t=>{E.test(t)&&n(e)<1e3&&l(e,t)}]})(),a=v();return[(e,t,n,s=[],l=()=>[])=>{r??=ee;const c=o(1);var i,d;return w(a,c,[e,t,n,s,l]),i=y(t,n??[""],z),d=c,i?.add(d),c},(e,t,...o)=>s(((e,t=[""])=>{const r=[],o=(e,c)=>c==n(t)?l(r,e):null===t[c]?k(e,e=>o(e,c+1)):s([t[c],null],t=>o(L(e,t),c+1));return o(e,0),r})(e,t),e=>k(e,e=>L(a,e)[0](r,...t??[],...o))),e=>t(L(a,e),([,t,n])=>(y(t,n??[""],void 0,t=>(C(t,e),p(t)?1:0)),w(a,e),c(e),n)),o=>t(L(a,o),([t,,o=[],l,c])=>{const i=(...a)=>{const d=n(a);d==n(o)?t(r,...a,...c(a)):e(o[d])?s(l[d]?.(...a)??[],e=>i(...a,e)):i(...a,o[d])};i()})]})(),O=v(),T=v(),W=[],$=[],m=(t,n)=>{M=0,a.transaction(()=>{const[r,s]=L(O,n);k(r,(n,r)=>k(n,(n,s)=>k(n,(n,o)=>((t,n,r,s,o)=>e(o)?t.delCell(n,r,s,!0):t.setCell(n,r,s,o))(a,r,s,o,n[t])))),k(s,(n,r)=>((t,n,r)=>e(r)?t.delValue(n):t.setValue(n,r))(a,r,n[t]))}),M=1},q=e=>{w(O,e),w(T,e),x(b,[e])},D=(e,t)=>s(((e,t)=>e.splice(0,t))(e,t??n(e)),q),G=()=>D(W,n(W)-V),H=()=>t(u,()=>{l(W,u),G(),D($),u=void 0,I=1}),J=()=>{u=c(W),I=1};let K,N;const P=(t="")=>(e(u)&&(u=""+g++,w(O,u,[A,F]),Y(u,t),A=v(),F=v(),I=1),u),Q=()=>{o(W)||(((e,...t)=>{e.unshift(...t)})($,P()),m(0,u),u=c(W),I=1)},R=()=>{o($)||(l(W,u),u=i($),m(1,u),I=1)},U=()=>{I&&(x(_),I=0)},X=e=>{const t=P(e);return U(),t},Y=(e,t)=>(Z(e)&&L(T,e)!==t&&(w(T,e,t),x(b,[e])),ee),Z=e=>h(O,e),ee={setSize:e=>(V=e,G(),ee),addCheckpoint:X,setCheckpoint:Y,getStore:()=>a,getCheckpointIds:()=>[[...W],u,[...$]],forEachCheckpoint:e=>{return t=e,k(T,(e,n)=>t(n,e));var t},hasCheckpoint:Z,getCheckpoint:e=>L(T,e),goBackward:()=>(Q(),U(),ee),goForward:()=>(R(),U(),ee),goTo:t=>{const n=r(W,t)?Q:r($,t)?R:null;for(;!e(n)&&t!=u;)n();return U(),ee},addCheckpointIdsListener:e=>j(e,_),addCheckpointListener:(e,t)=>j(t,b,[e]),delListener:e=>(B(e),ee),clear:()=>(D(W),D($),e(u)||q(u),u=void 0,g=0,X(),ee),clearForward:()=>(o($)||(D($),x(_)),ee),destroy:()=>{a.delListener(K),a.delListener(N)},getListenerStats:()=>({checkpointIds:d(_),checkpoint:d(b)}),_registerListeners:()=>{K=a.addCellListener(null,null,null,(e,t,n,r,s,o)=>{if(M){H();const e=S(A,t,v),l=S(e,n,v),c=S(l,r,()=>[o,void 0]);c[1]=s,c[0]===s&&p(w(l,r))&&p(w(e,n))&&p(w(A,t))&&J(),U()}}),N=a.addValueListener(null,(e,t,n,r)=>{if(M){H();const e=S(F,t,()=>[r,void 0]);e[1]=n,e[0]===n&&p(w(F,t))&&J(),U()}})}};return f(ee.clear())})(u));const g=a.get(u);return g._registerListeners(),g}})();export{I as createCheckpoints};
Binary file
@@ -1 +1 @@
1
- const e=e=>null==e,t=(t,n,r)=>e(t)?r?.():n(t),n=e=>e.length,r=(e,t)=>e.includes(t),s=(e,t)=>e.forEach(t),o=e=>0==n(e),l=(e,...t)=>e.push(...t),c=e=>e.pop(),i=e=>e.shift(),a=e=>e?.size??0,d=(u=a,e=>{return t=(e,t)=>e+u(t),g(e).reduce(t,0);var t});var u;const h=(e,t)=>e?.has(t)??!1,p=t=>e(t)||0==a(t),g=e=>[...e?.values()??[]],k=(e,t)=>e?.forEach(t),C=(e,t)=>e?.delete(t),f=Object.freeze,v=e=>new Map(e),L=(e,t)=>e?.get(t),w=(t,n,r)=>e(r)?(C(t,n),t):t?.set(n,r),S=(e,t,n,r)=>(h(e,t)?r?.(L(e,t)):w(e,t,n()),L(e,t)),y=(e,r,s,o,l=0)=>t((s?S:L)(e,r[l],l>n(r)-2?s:v),(t=>{if(l>n(r)-2)return o?.(t)&&w(e,r[l]),t;const c=y(t,r,s,o,l+1);return p(t)&&w(e,r[l]),c})),z=t=>new Set(Array.isArray(t)||e(t)?t:[t]),E=/^\d+$/,I=(()=>{const a=new WeakMap;return u=>{a.has(u)||a.set(u,(a=>{let u,g,I,V=100,A=v(),F=v(),M=1;const _=v(),b=v(),[j,x,B]=(()=>{let r;const[o,c]=(()=>{const e=[];let t=0;return[n=>(n?i(e):null)??""+t++,t=>{E.test(t)&&n(e)<1e3&&l(e,t)}]})(),a=v();return[(e,t,n,s=[],l=()=>[])=>{r??=ee;const c=o(1);var i,d;return w(a,c,[e,t,n,s,l]),i=y(t,n??[""],z),d=c,i?.add(d),c},(e,t,...o)=>s(((e,t=[""])=>{const r=[],o=(e,c)=>c==n(t)?l(r,e):null===t[c]?k(e,(e=>o(e,c+1))):s([t[c],null],(t=>o(L(e,t),c+1)));return o(e,0),r})(e,t),(e=>k(e,(e=>L(a,e)[0](r,...t??[],...o))))),e=>t(L(a,e),(([,t,n])=>(y(t,n??[""],void 0,(t=>(C(t,e),p(t)?1:0))),w(a,e),c(e),n))),o=>t(L(a,o),(([t,,o=[],l,c])=>{const i=(...a)=>{const d=n(a);d==n(o)?t(r,...a,...c(a)):e(o[d])?s(l[d]?.(...a)??[],(e=>i(...a,e))):i(...a,o[d])};i()}))]})(),O=v(),T=v(),W=[],$=[],m=(t,n)=>{M=0,a.transaction((()=>{const[r,s]=L(O,n);k(r,((n,r)=>k(n,((n,s)=>k(n,((n,o)=>((t,n,r,s,o)=>e(o)?t.delCell(n,r,s,!0):t.setCell(n,r,s,o))(a,r,s,o,n[t]))))))),k(s,((n,r)=>((t,n,r)=>e(r)?t.delValue(n):t.setValue(n,r))(a,r,n[t])))})),M=1},q=e=>{w(O,e),w(T,e),x(b,[e])},D=(e,t)=>s(((e,t)=>e.splice(0,t))(e,t??n(e)),q),G=()=>D(W,n(W)-V),H=()=>t(u,(()=>{l(W,u),G(),D($),u=void 0,I=1})),J=()=>{u=c(W),I=1};let K,N;const P=(t="")=>(e(u)&&(u=""+g++,w(O,u,[A,F]),Y(u,t),A=v(),F=v(),I=1),u),Q=()=>{o(W)||(((e,...t)=>{e.unshift(...t)})($,P()),m(0,u),u=c(W),I=1)},R=()=>{o($)||(l(W,u),u=i($),m(1,u),I=1)},U=()=>{I&&(x(_),I=0)},X=e=>{const t=P(e);return U(),t},Y=(e,t)=>(Z(e)&&L(T,e)!==t&&(w(T,e,t),x(b,[e])),ee),Z=e=>h(O,e),ee={setSize:e=>(V=e,G(),ee),addCheckpoint:X,setCheckpoint:Y,getStore:()=>a,getCheckpointIds:()=>[[...W],u,[...$]],forEachCheckpoint:e=>{return t=e,k(T,((e,n)=>t(n,e)));var t},hasCheckpoint:Z,getCheckpoint:e=>L(T,e),goBackward:()=>(Q(),U(),ee),goForward:()=>(R(),U(),ee),goTo:t=>{const n=r(W,t)?Q:r($,t)?R:null;for(;!e(n)&&t!=u;)n();return U(),ee},addCheckpointIdsListener:e=>j(e,_),addCheckpointListener:(e,t)=>j(t,b,[e]),delListener:e=>(B(e),ee),clear:()=>(D(W),D($),e(u)||q(u),u=void 0,g=0,X(),ee),clearForward:()=>(o($)||(D($),x(_)),ee),destroy:()=>{a.delListener(K),a.delListener(N)},getListenerStats:()=>({checkpointIds:d(_),checkpoint:d(b)}),_registerListeners:()=>{K=a.addCellListener(null,null,null,((e,t,n,r,s,o)=>{if(M){H();const e=S(A,t,v),l=S(e,n,v),c=S(l,r,(()=>[o,void 0]));c[1]=s,c[0]===s&&p(w(l,r))&&p(w(e,n))&&p(w(A,t))&&J(),U()}})),N=a.addValueListener(null,((e,t,n,r)=>{if(M){H();const e=S(F,t,(()=>[r,void 0]));e[1]=n,e[0]===n&&p(w(F,t))&&J(),U()}}))}};return f(ee.clear())})(u));const g=a.get(u);return g._registerListeners(),g}})();export{I as createCheckpoints};
1
+ const e=e=>null==e,t=(t,n,r)=>e(t)?r?.():n(t),n=e=>e.length,r=(e,t)=>e.includes(t),s=(e,t)=>e.forEach(t),o=e=>0==n(e),l=(e,...t)=>e.push(...t),c=e=>e.pop(),i=e=>e.shift(),a=e=>e?.size??0,d=(u=a,e=>{return t=(e,t)=>e+u(t),g(e).reduce(t,0);var t});var u;const h=(e,t)=>e?.has(t)??!1,p=t=>e(t)||0==a(t),g=e=>[...e?.values()??[]],k=(e,t)=>e?.forEach(t),C=(e,t)=>e?.delete(t),f=Object.freeze,v=e=>new Map(e),L=(e,t)=>e?.get(t),w=(t,n,r)=>e(r)?(C(t,n),t):t?.set(n,r),S=(e,t,n,r)=>(h(e,t)?r?.(L(e,t)):w(e,t,n()),L(e,t)),y=(e,r,s,o,l=0)=>t((s?S:L)(e,r[l],l>n(r)-2?s:v),t=>{if(l>n(r)-2)return o?.(t)&&w(e,r[l]),t;const c=y(t,r,s,o,l+1);return p(t)&&w(e,r[l]),c}),z=t=>new Set(Array.isArray(t)||e(t)?t:[t]),E=/^\d+$/,I=(()=>{const a=new WeakMap;return u=>{a.has(u)||a.set(u,(a=>{let u,g,I,V=100,A=v(),F=v(),M=1;const _=v(),b=v(),[j,x,B]=(()=>{let r;const[o,c]=(()=>{const e=[];let t=0;return[n=>(n?i(e):null)??""+t++,t=>{E.test(t)&&n(e)<1e3&&l(e,t)}]})(),a=v();return[(e,t,n,s=[],l=()=>[])=>{r??=ee;const c=o(1);var i,d;return w(a,c,[e,t,n,s,l]),i=y(t,n??[""],z),d=c,i?.add(d),c},(e,t,...o)=>s(((e,t=[""])=>{const r=[],o=(e,c)=>c==n(t)?l(r,e):null===t[c]?k(e,e=>o(e,c+1)):s([t[c],null],t=>o(L(e,t),c+1));return o(e,0),r})(e,t),e=>k(e,e=>L(a,e)[0](r,...t??[],...o))),e=>t(L(a,e),([,t,n])=>(y(t,n??[""],void 0,t=>(C(t,e),p(t)?1:0)),w(a,e),c(e),n)),o=>t(L(a,o),([t,,o=[],l,c])=>{const i=(...a)=>{const d=n(a);d==n(o)?t(r,...a,...c(a)):e(o[d])?s(l[d]?.(...a)??[],e=>i(...a,e)):i(...a,o[d])};i()})]})(),O=v(),T=v(),W=[],$=[],m=(t,n)=>{M=0,a.transaction(()=>{const[r,s]=L(O,n);k(r,(n,r)=>k(n,(n,s)=>k(n,(n,o)=>((t,n,r,s,o)=>e(o)?t.delCell(n,r,s,!0):t.setCell(n,r,s,o))(a,r,s,o,n[t])))),k(s,(n,r)=>((t,n,r)=>e(r)?t.delValue(n):t.setValue(n,r))(a,r,n[t]))}),M=1},q=e=>{w(O,e),w(T,e),x(b,[e])},D=(e,t)=>s(((e,t)=>e.splice(0,t))(e,t??n(e)),q),G=()=>D(W,n(W)-V),H=()=>t(u,()=>{l(W,u),G(),D($),u=void 0,I=1}),J=()=>{u=c(W),I=1};let K,N;const P=(t="")=>(e(u)&&(u=""+g++,w(O,u,[A,F]),Y(u,t),A=v(),F=v(),I=1),u),Q=()=>{o(W)||(((e,...t)=>{e.unshift(...t)})($,P()),m(0,u),u=c(W),I=1)},R=()=>{o($)||(l(W,u),u=i($),m(1,u),I=1)},U=()=>{I&&(x(_),I=0)},X=e=>{const t=P(e);return U(),t},Y=(e,t)=>(Z(e)&&L(T,e)!==t&&(w(T,e,t),x(b,[e])),ee),Z=e=>h(O,e),ee={setSize:e=>(V=e,G(),ee),addCheckpoint:X,setCheckpoint:Y,getStore:()=>a,getCheckpointIds:()=>[[...W],u,[...$]],forEachCheckpoint:e=>{return t=e,k(T,(e,n)=>t(n,e));var t},hasCheckpoint:Z,getCheckpoint:e=>L(T,e),goBackward:()=>(Q(),U(),ee),goForward:()=>(R(),U(),ee),goTo:t=>{const n=r(W,t)?Q:r($,t)?R:null;for(;!e(n)&&t!=u;)n();return U(),ee},addCheckpointIdsListener:e=>j(e,_),addCheckpointListener:(e,t)=>j(t,b,[e]),delListener:e=>(B(e),ee),clear:()=>(D(W),D($),e(u)||q(u),u=void 0,g=0,X(),ee),clearForward:()=>(o($)||(D($),x(_)),ee),destroy:()=>{a.delListener(K),a.delListener(N)},getListenerStats:()=>({checkpointIds:d(_),checkpoint:d(b)}),_registerListeners:()=>{K=a.addCellListener(null,null,null,(e,t,n,r,s,o)=>{if(M){H();const e=S(A,t,v),l=S(e,n,v),c=S(l,r,()=>[o,void 0]);c[1]=s,c[0]===s&&p(w(l,r))&&p(w(e,n))&&p(w(A,t))&&J(),U()}}),N=a.addValueListener(null,(e,t,n,r)=>{if(M){H();const e=S(F,t,()=>[r,void 0]);e[1]=n,e[0]===n&&p(w(F,t))&&J(),U()}})}};return f(ee.clear())})(u));const g=a.get(u);return g._registerListeners(),g}})();export{I as createCheckpoints};
@@ -1 +1 @@
1
- const e=(e,t="",n)=>e.split(t,n),t=globalThis,n=Math,r=n.max,o=n.floor,a=e=>null==e,c=(e,t)=>e.map(t),s=(e,t,n)=>e.reduce(t,n),l=Object,i=l.entries,u=e=>new Map(e),p=e("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"),d=u(c(p,((e,t)=>[e,t]))),f=e=>p[63&e],m=(e,t)=>{return n=d,r=e[t],n?.get(r)??0;var n,r},g=t.crypto?e=>t.crypto.getRandomValues(e):e=>c(e,(()=>o(256*n.random()))),w=(e=16)=>s(g(new Uint8Array(e)),((e,t)=>e+f(t)),""),y=JSON.stringify,h=new t.TextEncoder,v=e=>{let t=2166136261;var n;return n=e=>{t^=e,t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)},h.encode(e).forEach(n),t>>>0},x=(e,t)=>(e^t)>>>0,E=e=>s(i(e),((e,[t,n])=>x(e,M(t,n)^M(t,0))),0),M=(e,t)=>v(e+":"+t),b=(e,t)=>v(y(e??null,((e,t)=>t instanceof Map?l.fromEntries([...t]):t))+":"+t),O=b,T=M,j=E,A=M,D=e=>s(i(e),((e,[t,n])=>x(e,M(t,n))),0),J=M,N=D,R=2**36,S=2**30,U=2**24,V=2**18,k=4096,q=e=>{const t=v(e);return f(t/U)+f(t/V)+f(t/k)+f(t/64)+f(t)},z=(e,t=Date.now)=>{let n=0,o=-1;const c=(l=q,i=()=>w(5),a(s=e)?i?.():l(s));var s,l,i;const u=e=>{const c=n,[s,l]=a(e)||""==e?[0,0]:d(e);n=r(c,s,t()),o=n==c?n==s?r(o,l):o:n==s?l:-1},p=(e,t,n)=>f(e/R)+f(e/S)+f(e/U)+f(e/V)+f(e/k)+f(e/64)+f(e)+f(t/V)+f(t/k)+f(t/64)+f(t)+(a(n)?c:q(n)),d=e=>[m(e,0)*R+m(e,1)*S+m(e,2)*U+m(e,3)*V+m(e,4)*k+64*m(e,5)+m(e,6),m(e,7)*V+m(e,8)*k+64*m(e,9)+m(e,10),e.slice(11)];return[()=>(u(),p(n,++o)),u,p,d,()=>n,()=>o,()=>c]},B=(e,t)=>(e??0)<(t??0)?-1:1;export{x as addOrRemoveHash,B as defaultSorter,O as getCellHash,T as getCellInRowHash,v as getHash,z as getHlcFunctions,j as getRowHash,A as getRowInTableHash,D as getTableHash,J as getTableInTablesHash,N as getTablesHash,w as getUniqueId,b as getValueHash,M as getValueInValuesHash,E as getValuesHash};
1
+ const e=(e,t="",n)=>e.split(t,n),t=globalThis,n=Math,r=n.max,o=n.floor,a=e=>null==e,c=(e,t)=>e.map(t),s=(e,t,n)=>e.reduce(t,n),l=Object,i=l.entries,u=e=>new Map(e),p=e("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"),d=u(c(p,(e,t)=>[e,t])),f=e=>p[63&e],m=(e,t)=>{return n=d,r=e[t],n?.get(r)??0;var n,r},g=t.crypto?e=>t.crypto.getRandomValues(e):e=>c(e,()=>o(256*n.random())),w=(e=16)=>s(g(new Uint8Array(e)),(e,t)=>e+f(t),""),y=JSON.stringify,h=new t.TextEncoder,v=e=>{let t=2166136261;var n;return n=e=>{t^=e,t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)},h.encode(e).forEach(n),t>>>0},x=(e,t)=>(e^t)>>>0,E=e=>s(i(e),(e,[t,n])=>x(e,M(t,n)^M(t,0)),0),M=(e,t)=>v(e+":"+t),b=(e,t)=>v(y(e??null,(e,t)=>t instanceof Map?l.fromEntries([...t]):t)+":"+t),O=b,T=M,j=E,A=M,D=e=>s(i(e),(e,[t,n])=>x(e,M(t,n)),0),J=M,N=D,R=2**36,S=2**30,U=2**24,V=2**18,k=4096,q=e=>{const t=v(e);return f(t/U)+f(t/V)+f(t/k)+f(t/64)+f(t)},z=(e,t=Date.now)=>{let n=0,o=-1;const c=(l=q,i=()=>w(5),a(s=e)?i?.():l(s));var s,l,i;const u=e=>{const c=n,[s,l]=a(e)||""==e?[0,0]:d(e);n=r(c,s,t()),o=n==c?n==s?r(o,l):o:n==s?l:-1},p=(e,t,n)=>f(e/R)+f(e/S)+f(e/U)+f(e/V)+f(e/k)+f(e/64)+f(e)+f(t/V)+f(t/k)+f(t/64)+f(t)+(a(n)?c:q(n)),d=e=>[m(e,0)*R+m(e,1)*S+m(e,2)*U+m(e,3)*V+m(e,4)*k+64*m(e,5)+m(e,6),m(e,7)*V+m(e,8)*k+64*m(e,9)+m(e,10),e.slice(11)];return[()=>(u(),p(n,++o)),u,p,d,()=>n,()=>o,()=>c]},B=(e,t)=>(e??0)<(t??0)?-1:1;export{x as addOrRemoveHash,B as defaultSorter,O as getCellHash,T as getCellInRowHash,v as getHash,z as getHlcFunctions,j as getRowHash,A as getRowInTableHash,D as getTableHash,J as getTableInTablesHash,N as getTablesHash,w as getUniqueId,b as getValueHash,M as getValueInValuesHash,E as getValuesHash};
Binary file
@@ -1 +1 @@
1
- const e=(e,t="",n)=>e.split(t,n),t=globalThis,n=Math,r=n.max,o=n.floor,a=e=>null==e,c=(e,t)=>e.map(t),s=(e,t,n)=>e.reduce(t,n),l=Object,i=l.entries,u=e=>new Map(e),p=e("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"),d=u(c(p,((e,t)=>[e,t]))),f=e=>p[63&e],m=(e,t)=>{return n=d,r=e[t],n?.get(r)??0;var n,r},g=t.crypto?e=>t.crypto.getRandomValues(e):e=>c(e,(()=>o(256*n.random()))),w=(e=16)=>s(g(new Uint8Array(e)),((e,t)=>e+f(t)),""),y=JSON.stringify,h=new t.TextEncoder,v=e=>{let t=2166136261;var n;return n=e=>{t^=e,t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)},h.encode(e).forEach(n),t>>>0},x=(e,t)=>(e^t)>>>0,E=e=>s(i(e),((e,[t,n])=>x(e,M(t,n)^M(t,0))),0),M=(e,t)=>v(e+":"+t),b=(e,t)=>v(y(e??null,((e,t)=>t instanceof Map?l.fromEntries([...t]):t))+":"+t),O=b,T=M,j=E,A=M,D=e=>s(i(e),((e,[t,n])=>x(e,M(t,n))),0),J=M,N=D,R=2**36,S=2**30,U=2**24,V=2**18,k=4096,q=e=>{const t=v(e);return f(t/U)+f(t/V)+f(t/k)+f(t/64)+f(t)},z=(e,t=Date.now)=>{let n=0,o=-1;const c=(l=q,i=()=>w(5),a(s=e)?i?.():l(s));var s,l,i;const u=e=>{const c=n,[s,l]=a(e)||""==e?[0,0]:d(e);n=r(c,s,t()),o=n==c?n==s?r(o,l):o:n==s?l:-1},p=(e,t,n)=>f(e/R)+f(e/S)+f(e/U)+f(e/V)+f(e/k)+f(e/64)+f(e)+f(t/V)+f(t/k)+f(t/64)+f(t)+(a(n)?c:q(n)),d=e=>[m(e,0)*R+m(e,1)*S+m(e,2)*U+m(e,3)*V+m(e,4)*k+64*m(e,5)+m(e,6),m(e,7)*V+m(e,8)*k+64*m(e,9)+m(e,10),e.slice(11)];return[()=>(u(),p(n,++o)),u,p,d,()=>n,()=>o,()=>c]},B=(e,t)=>(e??0)<(t??0)?-1:1;export{x as addOrRemoveHash,B as defaultSorter,O as getCellHash,T as getCellInRowHash,v as getHash,z as getHlcFunctions,j as getRowHash,A as getRowInTableHash,D as getTableHash,J as getTableInTablesHash,N as getTablesHash,w as getUniqueId,b as getValueHash,M as getValueInValuesHash,E as getValuesHash};
1
+ const e=(e,t="",n)=>e.split(t,n),t=globalThis,n=Math,r=n.max,o=n.floor,a=e=>null==e,c=(e,t)=>e.map(t),s=(e,t,n)=>e.reduce(t,n),l=Object,i=l.entries,u=e=>new Map(e),p=e("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"),d=u(c(p,(e,t)=>[e,t])),f=e=>p[63&e],m=(e,t)=>{return n=d,r=e[t],n?.get(r)??0;var n,r},g=t.crypto?e=>t.crypto.getRandomValues(e):e=>c(e,()=>o(256*n.random())),w=(e=16)=>s(g(new Uint8Array(e)),(e,t)=>e+f(t),""),y=JSON.stringify,h=new t.TextEncoder,v=e=>{let t=2166136261;var n;return n=e=>{t^=e,t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)},h.encode(e).forEach(n),t>>>0},x=(e,t)=>(e^t)>>>0,E=e=>s(i(e),(e,[t,n])=>x(e,M(t,n)^M(t,0)),0),M=(e,t)=>v(e+":"+t),b=(e,t)=>v(y(e??null,(e,t)=>t instanceof Map?l.fromEntries([...t]):t)+":"+t),O=b,T=M,j=E,A=M,D=e=>s(i(e),(e,[t,n])=>x(e,M(t,n)),0),J=M,N=D,R=2**36,S=2**30,U=2**24,V=2**18,k=4096,q=e=>{const t=v(e);return f(t/U)+f(t/V)+f(t/k)+f(t/64)+f(t)},z=(e,t=Date.now)=>{let n=0,o=-1;const c=(l=q,i=()=>w(5),a(s=e)?i?.():l(s));var s,l,i;const u=e=>{const c=n,[s,l]=a(e)||""==e?[0,0]:d(e);n=r(c,s,t()),o=n==c?n==s?r(o,l):o:n==s?l:-1},p=(e,t,n)=>f(e/R)+f(e/S)+f(e/U)+f(e/V)+f(e/k)+f(e/64)+f(e)+f(t/V)+f(t/k)+f(t/64)+f(t)+(a(n)?c:q(n)),d=e=>[m(e,0)*R+m(e,1)*S+m(e,2)*U+m(e,3)*V+m(e,4)*k+64*m(e,5)+m(e,6),m(e,7)*V+m(e,8)*k+64*m(e,9)+m(e,10),e.slice(11)];return[()=>(u(),p(n,++o)),u,p,d,()=>n,()=>o,()=>c]},B=(e,t)=>(e??0)<(t??0)?-1:1;export{x as addOrRemoveHash,B as defaultSorter,O as getCellHash,T as getCellInRowHash,v as getHash,z as getHlcFunctions,j as getRowHash,A as getRowInTableHash,D as getTableHash,J as getTableInTablesHash,N as getTablesHash,w as getUniqueId,b as getValueHash,M as getValueInValuesHash,E as getValuesHash};
Binary file