@spooky-sync/core 0.0.1-canary.32 → 0.0.1-canary.320
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/AGENTS.md +81 -0
- package/README.md +56 -16
- package/dist/index.d.ts +2034 -137
- package/dist/index.js +15137 -2434
- package/dist/live.d.ts +141 -0
- package/dist/live.js +709 -0
- package/dist/otel/index.d.ts +1 -1
- package/dist/otel/index.js +3 -3
- package/dist/pure.d.ts +337 -0
- package/dist/pure.js +24 -0
- package/dist/sqlite-open.js +379 -0
- package/dist/sqlite-worker.d.ts +1 -0
- package/dist/sqlite-worker.js +439 -0
- package/dist/sw.d.ts +207 -0
- package/dist/sw.js +393 -0
- package/dist/tabs-broker-worker.d.ts +8 -0
- package/dist/tabs-broker-worker.js +472 -0
- package/dist/types.d.ts +1811 -38
- package/dist/worker-edges.js +439 -0
- package/dist/worker-impersonation.js +60 -0
- package/dist/worker-ref-tables.d.ts +46 -0
- package/dist/worker-types.d.ts +112 -0
- package/dist/worker-types.js +73 -0
- package/package.json +27 -7
- package/scripts/check-broker-bundle.mjs +33 -0
- package/scripts/check-worker-entries.mjs +172 -0
- package/skills/sp00ky-core/SKILL.md +31 -6
- package/skills/sp00ky-core/references/config.md +6 -0
- package/src/boot/auth-flip.saga.test.ts +135 -0
- package/src/boot/auth-flip.saga.ts +77 -0
- package/src/boot/boot.saga.test.ts +180 -0
- package/src/boot/boot.saga.ts +142 -0
- package/src/boot/bucket-switch.saga.test.ts +187 -0
- package/src/boot/bucket-switch.saga.ts +133 -0
- package/src/boot/preload.saga.test.ts +51 -0
- package/src/boot/preload.saga.ts +31 -0
- package/src/bucket-blurhash.test.ts +148 -0
- package/src/build-globals.d.ts +12 -0
- package/src/client/bucket-handle.test.ts +117 -0
- package/src/client/bucket-handle.ts +227 -0
- package/src/client/router.test.ts +58 -0
- package/src/client/router.ts +100 -0
- package/src/client/runtime.test.ts +195 -0
- package/src/client/runtime.ts +296 -0
- package/src/client/services.test.ts +51 -0
- package/src/client/services.ts +404 -0
- package/src/client/sp00ky-client.test.ts +303 -0
- package/src/client/sp00ky-client.ts +586 -0
- package/src/events/events.test.ts +2 -1
- package/src/events/index.ts +3 -0
- package/src/index.ts +69 -1
- package/src/kernel/constants.test.ts +19 -0
- package/src/kernel/constants.ts +80 -0
- package/src/kernel/effects.test.ts +40 -0
- package/src/kernel/effects.ts +163 -0
- package/src/kernel/events.ts +57 -0
- package/src/kernel/interpreter.test.ts +116 -0
- package/src/kernel/interpreter.ts +148 -0
- package/src/kernel/saga.test.ts +89 -0
- package/src/kernel/saga.ts +73 -0
- package/src/live/index.test.ts +478 -0
- package/src/live/index.ts +1013 -0
- package/src/modules/app-release/index.test.ts +125 -0
- package/src/modules/app-release/index.ts +209 -0
- package/src/modules/auth/auth.local-first.test.ts +169 -0
- package/src/modules/auth/events/index.ts +9 -2
- package/src/modules/auth/impersonation-banner.ts +443 -0
- package/src/modules/auth/impersonation.integration.test.ts +205 -0
- package/src/modules/auth/impersonation.test.ts +377 -0
- package/src/modules/auth/impersonation.ts +179 -0
- package/src/modules/auth/index.ts +466 -19
- package/src/modules/crdt/crdt-field.ts +294 -0
- package/src/modules/crdt/crdt-hydration.test.ts +210 -0
- package/src/modules/crdt/crdt-reconnect.test.ts +195 -0
- package/src/modules/crdt/index.ts +463 -0
- package/src/modules/crdt/loro-loader.ts +25 -0
- package/src/modules/devtools/flags.ts +349 -0
- package/src/modules/devtools/index.ts +746 -95
- package/src/modules/devtools/mutations.test.ts +92 -0
- package/src/modules/devtools/mutations.ts +160 -0
- package/src/modules/devtools/notify-throttle.test.ts +166 -0
- package/src/modules/devtools/state-shape.test.ts +263 -0
- package/src/modules/devtools/storage-info.test.ts +79 -0
- package/src/modules/devtools/storage-info.ts +168 -0
- package/src/modules/devtools/versions.test.ts +74 -0
- package/src/modules/devtools/versions.ts +110 -0
- package/src/modules/feature-flag/index.test.ts +298 -0
- package/src/modules/feature-flag/index.ts +316 -0
- package/src/modules/ref-tables.test.ts +91 -0
- package/src/modules/ref-tables.ts +88 -0
- package/src/modules/web-push/index.test.ts +824 -0
- package/src/modules/web-push/index.ts +1027 -0
- package/src/mutation/jobs.test.ts +25 -0
- package/src/mutation/jobs.ts +41 -0
- package/src/mutation/mutation-id.test.ts +37 -0
- package/src/mutation/mutation-id.ts +35 -0
- package/src/mutation/pending-writes.integration.test.ts +175 -0
- package/src/mutation/push.saga.test.ts +285 -0
- package/src/mutation/push.saga.ts +217 -0
- package/src/mutation/rows.test.ts +231 -0
- package/src/mutation/rows.ts +427 -0
- package/src/mutation/tray.saga.test.ts +63 -0
- package/src/mutation/tray.saga.ts +48 -0
- package/src/mutation/write.saga.test.ts +316 -0
- package/src/mutation/write.saga.ts +268 -0
- package/src/otel/index.ts +10 -7
- package/src/pure.ts +65 -0
- package/src/push/types.ts +174 -0
- package/src/query/env.test.ts +23 -0
- package/src/query/env.ts +56 -0
- package/src/query/fetch.saga.test.ts +199 -0
- package/src/query/fetch.saga.ts +120 -0
- package/src/query/hash.test.ts +14 -0
- package/src/query/hash.ts +18 -0
- package/src/query/id-set-plan.test.ts +132 -0
- package/src/query/lifecycle.saga.test.ts +274 -0
- package/src/query/lifecycle.saga.ts +159 -0
- package/src/query/materialize.saga.test.ts +115 -0
- package/src/query/materialize.saga.ts +84 -0
- package/src/query/materialize.test.ts +58 -0
- package/src/query/materialize.ts +57 -0
- package/src/query/membership.saga.test.ts +350 -0
- package/src/query/membership.saga.ts +278 -0
- package/src/query/membership.test.ts +118 -0
- package/src/query/membership.ts +201 -0
- package/src/query/register.saga.test.ts +311 -0
- package/src/query/register.saga.ts +229 -0
- package/src/query/render-set.test.ts +47 -0
- package/src/query/render-set.ts +71 -0
- package/src/query/sql.test.ts +81 -0
- package/src/query/sql.ts +112 -0
- package/src/query/window-query.test.ts +70 -0
- package/src/query/window-query.ts +195 -0
- package/src/services/blobs/blob-cache.test.ts +359 -0
- package/src/services/blobs/blob-cache.ts +603 -0
- package/src/services/blobs/blob-manifest.ts +227 -0
- package/src/services/blobs/blob-store.test.ts +77 -0
- package/src/services/blobs/blob-store.ts +359 -0
- package/src/services/blobs/blob.fixture.ts +90 -0
- package/src/services/blobs/index.ts +70 -0
- package/src/services/database/cache-engine.ts +199 -0
- package/src/services/database/connection-supervisor.test.ts +318 -0
- package/src/services/database/connection-supervisor.ts +422 -0
- package/src/services/database/database.query-timeout.test.ts +140 -0
- package/src/services/database/database.responses.test.ts +43 -0
- package/src/services/database/database.ts +146 -61
- package/src/services/database/engine-factory.ts +33 -0
- package/src/services/database/errors.ts +34 -0
- package/src/services/database/events/index.ts +2 -1
- package/src/services/database/index.ts +7 -0
- package/src/services/database/landed-body-clear.integration.test.ts +236 -0
- package/src/services/database/local-migrator.integration.test.ts +110 -0
- package/src/services/database/local-migrator.ts +59 -16
- package/src/services/database/local.test.ts +64 -0
- package/src/services/database/local.ts +487 -63
- package/src/services/database/plan-render.test.ts +159 -0
- package/src/services/database/plan-render.ts +108 -0
- package/src/services/database/relation-resolver.test.ts +484 -0
- package/src/services/database/relation-resolver.ts +0 -0
- package/src/services/database/remote.ts +255 -6
- package/src/services/database/sqlite-cache-engine.test.ts +617 -0
- package/src/services/database/sqlite-cache-engine.timeout.test.ts +61 -0
- package/src/services/database/sqlite-cache-engine.ts +1372 -0
- package/src/services/database/sqlite-devtools-queries.integration.test.ts +143 -0
- package/src/services/database/sqlite-devtools-queries.test.ts +154 -0
- package/src/services/database/sqlite-lock-verify.test.ts +33 -0
- package/src/services/database/sqlite-lock-verify.ts +45 -0
- package/src/services/database/sqlite-open.test.ts +150 -0
- package/src/services/database/sqlite-open.ts +164 -0
- package/src/services/database/sqlite-plan-sql.test.ts +145 -0
- package/src/services/database/sqlite-plan-sql.ts +182 -0
- package/src/services/database/sqlite-projection.test.ts +121 -0
- package/src/services/database/sqlite-select.integration.test.ts +185 -0
- package/src/services/database/sqlite-select.test.ts +261 -0
- package/src/services/database/sqlite-select.ts +131 -0
- package/src/services/database/sqlite-transport.fixture.ts +30 -0
- package/src/services/database/sqlite-transport.ts +224 -0
- package/src/services/database/sqlite-worker.ts +437 -0
- package/src/services/database/surql-translate.ts +416 -0
- package/src/services/database/surreal-cache-engine.ts +161 -0
- package/src/services/logger/index.test.ts +132 -0
- package/src/services/logger/index.ts +189 -7
- package/src/services/persistence/localstorage.ts +2 -2
- package/src/services/persistence/resilient.ts +10 -3
- package/src/services/persistence/surrealdb.ts +4 -4
- package/src/services/stream-processor/index.ts +783 -68
- package/src/services/stream-processor/permissions.test.ts +47 -0
- package/src/services/stream-processor/permissions.ts +53 -0
- package/src/services/stream-processor/stream-processor.batch.test.ts +186 -0
- package/src/services/stream-processor/stream-processor.prime.test.ts +198 -0
- package/src/services/stream-processor/stream-processor.reset.test.ts +226 -0
- package/src/services/stream-processor/stream-processor.test.ts +1 -1
- package/src/services/stream-processor/wasm-types.ts +58 -2
- package/src/services/tabs/broker-client.ts +283 -0
- package/src/services/tabs/broker.test.ts +327 -0
- package/src/services/tabs/coordinator.test.ts +386 -0
- package/src/services/tabs/coordinator.ts +638 -0
- package/src/services/tabs/fake-ports.fixture.ts +112 -0
- package/src/services/tabs/leader-locks.ts +75 -0
- package/src/services/tabs/protocol.ts +262 -0
- package/src/services/tabs/support.ts +36 -0
- package/src/services/tabs/tabs-broker-worker.ts +640 -0
- package/src/sp00ky.ts +5 -395
- package/src/state/client-state.ts +200 -0
- package/src/state/lifecycle.test.ts +141 -0
- package/src/state/lifecycle.ts +99 -0
- package/src/state/reducers.test.ts +304 -0
- package/src/state/reducers.ts +526 -0
- package/src/state/selectors.test.ts +175 -0
- package/src/state/selectors.ts +222 -0
- package/src/sw/index.test.ts +582 -0
- package/src/sw/index.ts +607 -0
- package/src/sw/store.ts +96 -0
- package/src/sync/connection.saga.test.ts +86 -0
- package/src/sync/connection.saga.ts +85 -0
- package/src/sync/live.saga.test.ts +178 -0
- package/src/sync/live.saga.ts +107 -0
- package/src/sync/policy.health.test.ts +56 -0
- package/src/sync/policy.test.ts +659 -0
- package/src/sync/policy.ts +502 -0
- package/src/sync/poll.saga.test.ts +51 -0
- package/src/sync/poll.saga.ts +36 -0
- package/src/sync/tabs.saga.test.ts +78 -0
- package/src/sync/tabs.saga.ts +96 -0
- package/src/testing/adapters.ts +133 -0
- package/src/testing/build.ts +63 -0
- package/src/testing/fake-services.ts +48 -0
- package/src/testing/run-pure.test.ts +92 -0
- package/src/testing/run-pure.ts +128 -0
- package/src/testing/services.ts +17 -0
- package/src/types.ts +624 -10
- package/src/utils/blurhash.ts +90 -0
- package/src/utils/edges.ts +39 -0
- package/src/utils/error-classification.test.ts +54 -0
- package/src/utils/error-classification.ts +25 -0
- package/src/utils/index.ts +78 -12
- package/src/utils/parser.test.ts +67 -102
- package/src/utils/parser.ts +64 -2
- package/src/utils/semver.test.ts +32 -0
- package/src/utils/semver.ts +30 -0
- package/src/utils/sha256.ts +15 -0
- package/src/utils/surql.ts +30 -18
- package/src/utils/utils.test.ts +3 -2
- package/tsdown.config.ts +117 -3
- package/vitest.config.ts +48 -0
- package/src/modules/cache/index.ts +0 -241
- package/src/modules/cache/types.ts +0 -19
- package/src/modules/data/data.test.ts +0 -58
- package/src/modules/data/index.ts +0 -879
- package/src/modules/sync/engine.ts +0 -173
- package/src/modules/sync/events/index.ts +0 -77
- package/src/modules/sync/index.ts +0 -3
- package/src/modules/sync/queue/index.ts +0 -2
- package/src/modules/sync/queue/queue-down.ts +0 -89
- package/src/modules/sync/queue/queue-up.ts +0 -223
- package/src/modules/sync/scheduler.ts +0 -84
- package/src/modules/sync/sync.ts +0 -421
- package/src/modules/sync/utils.test.ts +0 -311
- package/src/modules/sync/utils.ts +0 -167
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Logger} from '../logger/index';
|
|
2
|
+
import { createLogger } from '../logger/index';
|
|
3
|
+
import type { LocalStore } from './cache-engine';
|
|
4
4
|
|
|
5
5
|
export interface SchemaRecord {
|
|
6
6
|
hash: string;
|
|
@@ -15,16 +15,23 @@ export const sha1 = async (str: string): Promise<string> => {
|
|
|
15
15
|
.join('');
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Local-only state a schema change must not throw away: the outbox, the
|
|
20
|
+
* failed-mutation tray and debounced patches not yet in the outbox. Cached
|
|
21
|
+
* rows refill from the server; these exist nowhere else.
|
|
22
|
+
*/
|
|
23
|
+
const KEPT_TABLES = ['_00_pending_mutations', '_00_failed_mutations', '_00_pending_writes'] as const;
|
|
24
|
+
|
|
18
25
|
export class LocalMigrator {
|
|
19
26
|
private logger: Logger;
|
|
20
27
|
|
|
21
28
|
constructor(
|
|
22
|
-
private localDb:
|
|
29
|
+
private localDb: LocalStore,
|
|
23
30
|
logger: Logger
|
|
24
31
|
) {
|
|
25
32
|
this.logger = logger.child({ service: 'LocalMigrator' });
|
|
26
|
-
logger?.child({ service: 'LocalMigrator' }) ??
|
|
27
|
-
createLogger('info').child({ service: 'LocalMigrator' });
|
|
33
|
+
void (logger?.child({ service: 'LocalMigrator' }) ??
|
|
34
|
+
createLogger('info').child({ service: 'LocalMigrator' }));
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
async provision(schemaSurql: string): Promise<void> {
|
|
@@ -40,13 +47,18 @@ export class LocalMigrator {
|
|
|
40
47
|
return;
|
|
41
48
|
}
|
|
42
49
|
|
|
50
|
+
const kept = await this.readKeptRows();
|
|
43
51
|
await this.recreateDatabase(database);
|
|
44
52
|
|
|
45
53
|
const systemSchema = `
|
|
46
54
|
DEFINE TABLE IF NOT EXISTS _00_stream_processor_state SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
47
|
-
DEFINE TABLE IF NOT EXISTS
|
|
55
|
+
DEFINE TABLE IF NOT EXISTS _00_view SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
56
|
+
DEFINE TABLE IF NOT EXISTS _00_window SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
57
|
+
DEFINE TABLE IF NOT EXISTS _00_failed_mutations SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
48
58
|
DEFINE TABLE IF NOT EXISTS _00_schema SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
49
59
|
DEFINE TABLE IF NOT EXISTS _00_pending_mutations SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
60
|
+
DEFINE TABLE IF NOT EXISTS _00_pending_writes SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
61
|
+
DEFINE TABLE IF NOT EXISTS _00_blob SCHEMALESS PERMISSIONS FOR select, create, update, delete WHERE true;
|
|
50
62
|
`;
|
|
51
63
|
const fullSchema = schemaSurql + '\n' + systemSchema;
|
|
52
64
|
|
|
@@ -71,7 +83,7 @@ export class LocalMigrator {
|
|
|
71
83
|
{ Category: 'sp00ky-client::LocalMigrator::provision' },
|
|
72
84
|
`[Provisioning] (${i + 1}/${statements.length}) Executing: ${statement.substring(0, 50)}...`
|
|
73
85
|
);
|
|
74
|
-
await this.localDb.
|
|
86
|
+
await this.localDb.queryUngated(statement);
|
|
75
87
|
this.logger.info(
|
|
76
88
|
{ Category: 'sp00ky-client::LocalMigrator::provision' },
|
|
77
89
|
`[Provisioning] (${i + 1}/${statements.length}) Done`
|
|
@@ -85,37 +97,68 @@ export class LocalMigrator {
|
|
|
85
97
|
}
|
|
86
98
|
}
|
|
87
99
|
|
|
100
|
+
await this.restoreKeptRows(kept);
|
|
88
101
|
await this.createHashRecord(hash);
|
|
89
102
|
}
|
|
90
103
|
|
|
104
|
+
private async readKeptRows(): Promise<Array<[string, unknown[]]>> {
|
|
105
|
+
const kept: Array<[string, unknown[]]> = [];
|
|
106
|
+
for (const table of KEPT_TABLES) {
|
|
107
|
+
try {
|
|
108
|
+
const [rows] = await this.localDb.queryUngated<[unknown[]]>(`SELECT * FROM ${table}`);
|
|
109
|
+
if (Array.isArray(rows) && rows.length > 0) kept.push([table, rows]);
|
|
110
|
+
} catch {
|
|
111
|
+
// A fresh store has no such table yet: nothing to keep.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return kept;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private async restoreKeptRows(kept: Array<[string, unknown[]]>): Promise<void> {
|
|
118
|
+
for (const [table, rows] of kept) {
|
|
119
|
+
try {
|
|
120
|
+
await this.localDb.queryUngated(`INSERT INTO ${table} $rows`, { rows });
|
|
121
|
+
this.logger.info(
|
|
122
|
+
{ table, count: rows.length, Category: 'sp00ky-client::LocalMigrator::provision' },
|
|
123
|
+
'[Provisioning] Kept local rows across the schema change'
|
|
124
|
+
);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
this.logger.error(
|
|
127
|
+
{ table, count: rows.length, error, Category: 'sp00ky-client::LocalMigrator::provision' },
|
|
128
|
+
'[Provisioning] Could not restore local rows after the schema change; they are lost'
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
91
134
|
private async isSchemaUpToDate(hash: string): Promise<boolean> {
|
|
92
135
|
try {
|
|
93
|
-
const [lastSchemaRecord] = await this.localDb.
|
|
136
|
+
const [lastSchemaRecord] = await this.localDb.queryUngated<any>(
|
|
94
137
|
`SELECT hash, created_at FROM ONLY _00_schema ORDER BY created_at DESC LIMIT 1;`
|
|
95
138
|
);
|
|
96
139
|
return lastSchemaRecord?.hash === hash;
|
|
97
|
-
} catch (
|
|
140
|
+
} catch (_error) {
|
|
98
141
|
return false;
|
|
99
142
|
}
|
|
100
143
|
}
|
|
101
144
|
|
|
102
145
|
private async recreateDatabase(database: string) {
|
|
103
146
|
try {
|
|
104
|
-
await this.localDb.
|
|
105
|
-
} catch (
|
|
147
|
+
await this.localDb.queryUngated(`DEFINE DATABASE _00_temp;`);
|
|
148
|
+
} catch (_e) {
|
|
106
149
|
// Ignore if exists
|
|
107
150
|
}
|
|
108
151
|
|
|
109
152
|
try {
|
|
110
|
-
await this.localDb.
|
|
153
|
+
await this.localDb.queryUngated(`
|
|
111
154
|
USE DB _00_temp;
|
|
112
155
|
REMOVE DATABASE ${database};
|
|
113
156
|
`);
|
|
114
|
-
} catch (
|
|
157
|
+
} catch (_e) {
|
|
115
158
|
// Ignore error if database doesn't exist
|
|
116
159
|
}
|
|
117
160
|
|
|
118
|
-
await this.localDb.
|
|
161
|
+
await this.localDb.queryUngated(`
|
|
119
162
|
DEFINE DATABASE ${database};
|
|
120
163
|
USE DB ${database};
|
|
121
164
|
`);
|
|
@@ -195,7 +238,7 @@ export class LocalMigrator {
|
|
|
195
238
|
}
|
|
196
239
|
|
|
197
240
|
private async createHashRecord(hash: string) {
|
|
198
|
-
await this.localDb.
|
|
241
|
+
await this.localDb.queryUngated(
|
|
199
242
|
`UPSERT _00_schema SET hash = $hash, created_at = time::now() WHERE hash = $hash;`,
|
|
200
243
|
{ hash }
|
|
201
244
|
);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { isLocalStoreOpenError } from './local';
|
|
3
|
+
|
|
4
|
+
// `LocalDatabaseService.connect` recovers (drops the store + reconnects, falling
|
|
5
|
+
// back to in-memory) only when the failure is the SurrealDB-WASM IndexedDB
|
|
6
|
+
// open/transaction error — NOT for unrelated errors. This pins the message match
|
|
7
|
+
// against the real error the engine throws so a recovery path doesn't silently
|
|
8
|
+
// stop triggering (or start swallowing unrelated failures).
|
|
9
|
+
describe('isLocalStoreOpenError', () => {
|
|
10
|
+
it('matches the real SurrealDB-WASM IndexedDB key-value store error', () => {
|
|
11
|
+
const real = new Error(
|
|
12
|
+
'There was a problem with the key-value store: There was a problem with a ' +
|
|
13
|
+
'transaction: An IndexedDB error occured: idb error'
|
|
14
|
+
);
|
|
15
|
+
expect(isLocalStoreOpenError(real)).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('matches on the individual signals (indexeddb / idb error / key-value store)', () => {
|
|
19
|
+
expect(isLocalStoreOpenError(new Error('IndexedDB is not available'))).toBe(true);
|
|
20
|
+
expect(isLocalStoreOpenError(new Error('idb error'))).toBe(true);
|
|
21
|
+
expect(isLocalStoreOpenError(new Error('problem with the key-value store'))).toBe(true);
|
|
22
|
+
// Non-Error inputs are stringified.
|
|
23
|
+
expect(isLocalStoreOpenError('An IndexedDB error occured')).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('does NOT match unrelated errors (so we never clear the store spuriously)', () => {
|
|
27
|
+
expect(isLocalStoreOpenError(new Error('WebSocket connection refused'))).toBe(false);
|
|
28
|
+
expect(isLocalStoreOpenError(new Error('Parse error: unexpected token'))).toBe(false);
|
|
29
|
+
expect(isLocalStoreOpenError(new Error('permission denied'))).toBe(false);
|
|
30
|
+
expect(isLocalStoreOpenError(null)).toBe(false);
|
|
31
|
+
expect(isLocalStoreOpenError(undefined)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Per-user local buckets: URL/name derivation and the SCOPE of the tier-2
|
|
36
|
+
// corruption drop. The drop must only ever match the failing bucket's store —
|
|
37
|
+
// a substring wipe would take every user's cache AND their un-pushed mutation
|
|
38
|
+
// outboxes down with one corrupt store.
|
|
39
|
+
import { bucketStoreName, bucketStoreUrl, matchesBucketStore } from './local';
|
|
40
|
+
|
|
41
|
+
describe('bucket store naming', () => {
|
|
42
|
+
it('derives the store url/name from the bucket id', () => {
|
|
43
|
+
expect(bucketStoreUrl('abc')).toBe('indxdb://sp00ky-abc');
|
|
44
|
+
expect(bucketStoreName('abc')).toBe('sp00ky-abc');
|
|
45
|
+
expect(bucketStoreUrl('anon')).toBe('indxdb://sp00ky-anon');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('matchesBucketStore', () => {
|
|
50
|
+
it('matches the exact store and derived names', () => {
|
|
51
|
+
expect(matchesBucketStore('sp00ky-abc', 'sp00ky-abc')).toBe(true);
|
|
52
|
+
expect(matchesBucketStore('sp00ky-abc-wal', 'sp00ky-abc')).toBe(true);
|
|
53
|
+
expect(matchesBucketStore('surrealdb/sp00ky-abc', 'sp00ky-abc')).toBe(true);
|
|
54
|
+
expect(matchesBucketStore('SP00KY-ABC', 'sp00ky-abc')).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("never matches another bucket's store", () => {
|
|
58
|
+
expect(matchesBucketStore('sp00ky-abcdef', 'sp00ky-abc')).toBe(false);
|
|
59
|
+
expect(matchesBucketStore('sp00ky-anon', 'sp00ky-abc')).toBe(false);
|
|
60
|
+
expect(matchesBucketStore('sp00ky', 'sp00ky-abc')).toBe(false);
|
|
61
|
+
// The legacy shared store is not any bucket's store.
|
|
62
|
+
expect(matchesBucketStore('sp00ky', 'sp00ky-anon')).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
});
|