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.
- package/@types/omni/index.d.ts +1 -0
- package/@types/omni/with-schemas/index.d.ts +1 -0
- package/@types/persisters/index.d.ts +4 -2
- package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +348 -0
- package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +381 -0
- package/@types/persisters/with-schemas/index.d.ts +4 -2
- package/@types/queries/index.d.ts +1 -1
- package/@types/queries/with-schemas/index.d.ts +1 -1
- package/LICENSE +1 -1
- package/min/checkpoints/index.js +1 -1
- package/min/checkpoints/index.js.gz +0 -0
- package/min/checkpoints/with-schemas/index.js +1 -1
- package/min/checkpoints/with-schemas/index.js.gz +0 -0
- package/min/common/index.js +1 -1
- package/min/common/index.js.gz +0 -0
- package/min/common/with-schemas/index.js +1 -1
- package/min/common/with-schemas/index.js.gz +0 -0
- package/min/index.js +1 -1
- package/min/index.js.gz +0 -0
- package/min/indexes/index.js +1 -1
- package/min/indexes/index.js.gz +0 -0
- package/min/indexes/with-schemas/index.js +1 -1
- package/min/indexes/with-schemas/index.js.gz +0 -0
- package/min/mergeable-store/index.js +1 -1
- package/min/mergeable-store/index.js.gz +0 -0
- package/min/mergeable-store/with-schemas/index.js +1 -1
- package/min/mergeable-store/with-schemas/index.js.gz +0 -0
- package/min/metrics/index.js +1 -1
- package/min/metrics/index.js.gz +0 -0
- package/min/metrics/with-schemas/index.js +1 -1
- package/min/metrics/with-schemas/index.js.gz +0 -0
- package/min/omni/index.js +1 -1
- package/min/omni/index.js.gz +0 -0
- package/min/omni/with-schemas/index.js +1 -1
- package/min/omni/with-schemas/index.js.gz +0 -0
- package/min/persisters/index.js +1 -1
- package/min/persisters/index.js.gz +0 -0
- package/min/persisters/persister-automerge/index.js +1 -1
- package/min/persisters/persister-automerge/index.js.gz +0 -0
- package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
- package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-browser/index.js +1 -1
- package/min/persisters/persister-browser/index.js.gz +0 -0
- package/min/persisters/persister-browser/with-schemas/index.js +1 -1
- package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-sql-storage/index.js +1 -0
- package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -0
- package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/index.js +1 -1
- package/min/persisters/persister-electric-sql/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
- package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-file/index.js +1 -1
- package/min/persisters/persister-file/index.js.gz +0 -0
- package/min/persisters/persister-file/with-schemas/index.js +1 -1
- package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/index.js +1 -1
- package/min/persisters/persister-indexed-db/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
- package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-libsql/index.js +1 -1
- package/min/persisters/persister-libsql/index.js.gz +0 -0
- package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
- package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/index.js +1 -1
- package/min/persisters/persister-partykit-client/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
- package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-partykit-server/index.js +1 -1
- package/min/persisters/persister-partykit-server/index.js.gz +0 -0
- package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
- package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-pglite/index.js +1 -1
- package/min/persisters/persister-pglite/index.js.gz +0 -0
- package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
- package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-postgres/index.js +1 -1
- package/min/persisters/persister-postgres/index.js.gz +0 -0
- package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
- package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-powersync/index.js +1 -1
- package/min/persisters/persister-powersync/index.js.gz +0 -0
- package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
- package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-remote/index.js +1 -1
- package/min/persisters/persister-remote/index.js.gz +0 -0
- package/min/persisters/persister-remote/with-schemas/index.js +1 -1
- package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/index.js +1 -1
- package/min/persisters/persister-sqlite3/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-yjs/index.js +1 -1
- package/min/persisters/persister-yjs/index.js.gz +0 -0
- package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
- package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
- package/min/persisters/with-schemas/index.js +1 -1
- package/min/persisters/with-schemas/index.js.gz +0 -0
- package/min/queries/index.js +1 -1
- package/min/queries/index.js.gz +0 -0
- package/min/queries/with-schemas/index.js +1 -1
- package/min/queries/with-schemas/index.js.gz +0 -0
- package/min/relationships/index.js +1 -1
- package/min/relationships/index.js.gz +0 -0
- package/min/relationships/with-schemas/index.js +1 -1
- package/min/relationships/with-schemas/index.js.gz +0 -0
- package/min/store/index.js +1 -1
- package/min/store/index.js.gz +0 -0
- package/min/store/with-schemas/index.js +1 -1
- package/min/store/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/index.js +1 -1
- package/min/synchronizers/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/index.js +1 -1
- package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/with-schemas/index.js +1 -1
- package/min/synchronizers/with-schemas/index.js.gz +0 -0
- package/min/ui-react/index.js +1 -1
- package/min/ui-react/index.js.gz +0 -0
- package/min/ui-react/with-schemas/index.js +1 -1
- package/min/ui-react/with-schemas/index.js.gz +0 -0
- package/min/ui-react-dom/index.js +1 -1
- package/min/ui-react-dom/index.js.gz +0 -0
- package/min/ui-react-dom/with-schemas/index.js +1 -1
- package/min/ui-react-dom/with-schemas/index.js.gz +0 -0
- package/min/ui-react-inspector/index.js +1 -1
- package/min/ui-react-inspector/index.js.gz +0 -0
- package/min/ui-react-inspector/with-schemas/index.js +1 -1
- package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
- package/min/with-schemas/index.js +1 -1
- package/min/with-schemas/index.js.gz +0 -0
- package/omni/index.js +4 -1
- package/omni/with-schemas/index.js +4 -1
- package/package.json +43 -7
- package/persisters/persister-browser/index.js +4 -1
- package/persisters/persister-browser/with-schemas/index.js +4 -1
- package/persisters/persister-durable-object-sql-storage/index.js +1391 -0
- package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1391 -0
- package/readme.md +2 -2
- package/ui-react-inspector/index.js +4 -1
- 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
|
|
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
|
|
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
|
|
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
package/min/checkpoints/index.js
CHANGED
|
@@ -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),
|
|
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),
|
|
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
|
package/min/common/index.js
CHANGED
|
@@ -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,(
|
|
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};
|
package/min/common/index.js.gz
CHANGED
|
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,(
|
|
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
|