@serfab/quereus-plugin-sereus 1.16.0 → 1.18.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/README.md +390 -384
- package/dist/compose-strand.js +6 -1
- package/dist/compose-strand.js.map +1 -1
- package/dist/empty-collections.d.ts +28 -0
- package/dist/empty-collections.js +108 -0
- package/dist/empty-collections.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin-browser.js +25 -25
- package/dist/plugin-browser.js.map +4 -4
- package/dist/types.d.ts +14 -0
- package/package.json +8 -8
- package/src/compose-strand.ts +13 -3
- package/src/empty-collections.ts +139 -0
- package/src/index.ts +1 -0
- package/src/types.ts +135 -121
package/dist/compose-strand.js
CHANGED
|
@@ -3,8 +3,11 @@ import optimysticPlugin from '@optimystic/quereus-plugin-optimystic/plugin';
|
|
|
3
3
|
import { STRAND_SCHEMA } from './strand-schema.js';
|
|
4
4
|
import { resolveStrandClusterSize, STRAND_CLUSTER_POLICY } from './cluster-size.js';
|
|
5
5
|
import { wrapStorageWithCache, disposeStorageCache } from './cached-storage.js';
|
|
6
|
+
import { createEmptyCollections } from './empty-collections.js';
|
|
6
7
|
const log = debug('sereus:plugin:strand');
|
|
7
8
|
const timing = debug('sereus:plugin:strand:timing');
|
|
9
|
+
/** The schemas whose tables a strand founder gives a collection: strand membership, then the sApp's. */
|
|
10
|
+
const FOUNDED_SCHEMAS = ['Strand', 'App'];
|
|
8
11
|
/**
|
|
9
12
|
* Release a composition's hold on the optimystic plugin. The transaction bridge goes first: its
|
|
10
13
|
* durability follower subscribes to the node's `StorageRepo`, and cadre-core keeps a strand's node
|
|
@@ -227,7 +230,8 @@ export async function composeStrand(db, options, platform) {
|
|
|
227
230
|
await releaseStorageCache();
|
|
228
231
|
throw err;
|
|
229
232
|
}
|
|
230
|
-
// 8. Return result with hydrate counts, the commit-durability listeners
|
|
233
|
+
// 8. Return result with hydrate counts, the commit-durability listeners, the founder's
|
|
234
|
+
// empty-collection step + shutdown handler.
|
|
231
235
|
// `shutdown` releases the plugin and stops the node only if this composition created it.
|
|
232
236
|
return {
|
|
233
237
|
vtables: [],
|
|
@@ -237,6 +241,7 @@ export async function composeStrand(db, options, platform) {
|
|
|
237
241
|
transactor: resolvedTransactor,
|
|
238
242
|
onCommitDurability: listener => pluginResult.onCommitDurability(listener),
|
|
239
243
|
onCommitFullyHeld: listener => pluginResult.onCommitFullyHeld(listener),
|
|
244
|
+
createEmptyCollections: except => createEmptyCollections(db, pluginResult.txnBridge, FOUNDED_SCHEMAS, except),
|
|
240
245
|
async shutdown() {
|
|
241
246
|
log('Shutting down strand connection %s', strandId);
|
|
242
247
|
await releaseOptimysticPlugin(pluginResult, createdNode);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose-strand.js","sourceRoot":"","sources":["../src/compose-strand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,gBAAgB,MAAM,8CAA8C,CAAC;AAM5E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"compose-strand.js","sourceRoot":"","sources":["../src/compose-strand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Database } from '@quereus/quereus';
|
|
2
|
+
import type { Collection, CollectionId } from '@optimystic/db-core';
|
|
3
|
+
/**
|
|
4
|
+
* The part of the Optimystic plugin's transaction bridge this module reads: the live registry of
|
|
5
|
+
* every collection a table opened (its main tree, index trees and unique-enforcement trees),
|
|
6
|
+
* filled as each table initializes.
|
|
7
|
+
*/
|
|
8
|
+
export interface CollectionRegistrySource {
|
|
9
|
+
getCollectionRegistry(): Map<CollectionId, Collection<unknown>>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Commit an empty collection for every Optimystic table declared in `schemaNames` that has none
|
|
13
|
+
* yet, except the tables named in `except`, and resolve to how many collections were committed.
|
|
14
|
+
*
|
|
15
|
+
* Opening a table whose collection was never committed stages a fresh empty one in this node's
|
|
16
|
+
* tracker and writes nothing (`Collection.createOrOpen`'s invented branch), and a SQL commit
|
|
17
|
+
* flushes only the trees it wrote to. So the step opens every table, which registers each of its
|
|
18
|
+
* trees with the bridge, then syncs every registered collection still in that invented state.
|
|
19
|
+
*
|
|
20
|
+
* `except` holds qualified table names (`'Strand.Header'`) whose collections the caller is about
|
|
21
|
+
* to create by writing rows: an insert writes every tree of its table, so each of those trees is
|
|
22
|
+
* left out whether or not it was opened here. A name that matches no declared Optimystic table
|
|
23
|
+
* throws, so a renamed table cannot quietly fall back to committing everything.
|
|
24
|
+
*
|
|
25
|
+
* Commits outside any SQL transaction whatever is staged in those collections, so it is only
|
|
26
|
+
* sound while nothing else writes through `db`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createEmptyCollections(db: Database, bridge: CollectionRegistrySource, schemaNames: readonly string[], except?: readonly string[]): Promise<number>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
import { defaultCollectionUri } from '@optimystic/quereus-plugin-optimystic';
|
|
3
|
+
const log = debug('sereus:plugin:empty-collections');
|
|
4
|
+
/**
|
|
5
|
+
* Commit an empty collection for every Optimystic table declared in `schemaNames` that has none
|
|
6
|
+
* yet, except the tables named in `except`, and resolve to how many collections were committed.
|
|
7
|
+
*
|
|
8
|
+
* Opening a table whose collection was never committed stages a fresh empty one in this node's
|
|
9
|
+
* tracker and writes nothing (`Collection.createOrOpen`'s invented branch), and a SQL commit
|
|
10
|
+
* flushes only the trees it wrote to. So the step opens every table, which registers each of its
|
|
11
|
+
* trees with the bridge, then syncs every registered collection still in that invented state.
|
|
12
|
+
*
|
|
13
|
+
* `except` holds qualified table names (`'Strand.Header'`) whose collections the caller is about
|
|
14
|
+
* to create by writing rows: an insert writes every tree of its table, so each of those trees is
|
|
15
|
+
* left out whether or not it was opened here. A name that matches no declared Optimystic table
|
|
16
|
+
* throws, so a renamed table cannot quietly fall back to committing everything.
|
|
17
|
+
*
|
|
18
|
+
* Commits outside any SQL transaction whatever is staged in those collections, so it is only
|
|
19
|
+
* sound while nothing else writes through `db`.
|
|
20
|
+
*/
|
|
21
|
+
export async function createEmptyCollections(db, bridge, schemaNames, except = []) {
|
|
22
|
+
const declared = optimysticTables(db, schemaNames);
|
|
23
|
+
const excluded = excludedTables(declared, except, schemaNames);
|
|
24
|
+
const tables = declared.filter(table => !excluded.includes(table));
|
|
25
|
+
await openTables(db, tables);
|
|
26
|
+
const registry = bridge.getCollectionRegistry();
|
|
27
|
+
assertMainCollectionsRegistered(registry, tables, schemaNames);
|
|
28
|
+
return await syncInventedCollections(registry, excluded.map(mainCollectionId));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Every Optimystic table the named schemas declare. A table reaches Optimystic either through its
|
|
32
|
+
* own `using` clause (an sApp's) or through the database's default vtab (the control tables), and
|
|
33
|
+
* both record `vtabModuleName`. None found means the filter no longer matches how those tables
|
|
34
|
+
* are backed, and carrying on would give no table a collection while appearing to work.
|
|
35
|
+
*/
|
|
36
|
+
function optimysticTables(db, schemaNames) {
|
|
37
|
+
const tables = schemaNames.flatMap(name => {
|
|
38
|
+
const schema = db.schemaManager.getSchema(name);
|
|
39
|
+
return schema
|
|
40
|
+
? Array.from(schema.getAllTables()).filter(table => !table.isView && table.vtabModuleName === 'optimystic')
|
|
41
|
+
: [];
|
|
42
|
+
});
|
|
43
|
+
if (tables.length === 0) {
|
|
44
|
+
throw new Error(`Schemas ${schemaNames.join(', ')} declare no optimystic table; cannot give their tables an empty collection`);
|
|
45
|
+
}
|
|
46
|
+
return tables;
|
|
47
|
+
}
|
|
48
|
+
/** The declared tables `except` names, compared case-insensitively as SQL identifiers are. */
|
|
49
|
+
function excludedTables(declared, except, schemaNames) {
|
|
50
|
+
return except.map(name => {
|
|
51
|
+
const table = declared.find(candidate => `${candidate.schemaName}.${candidate.name}`.toLowerCase() === name.toLowerCase());
|
|
52
|
+
if (!table) {
|
|
53
|
+
throw new Error(`Cannot leave ${name} out of the empty collections: schemas ${schemaNames.join(', ')} declare no optimystic table by that name`);
|
|
54
|
+
}
|
|
55
|
+
return table;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/** A read initializes the table's vtab, which is what opens and registers its collections. */
|
|
59
|
+
async function openTables(db, tables) {
|
|
60
|
+
for (const table of tables) {
|
|
61
|
+
for await (const _row of db.eval(`select 1 from ${table.schemaName}."${table.name}" limit 1`)) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A declared table whose main collection is not registered means the plugin's open or
|
|
68
|
+
* registration path has changed under this module; founding on would leave that table with no
|
|
69
|
+
* collection while appearing to have given every table one.
|
|
70
|
+
*/
|
|
71
|
+
function assertMainCollectionsRegistered(registry, tables, schemaNames) {
|
|
72
|
+
const unregistered = tables.filter(table => !registry.has(mainCollectionId(table)));
|
|
73
|
+
if (unregistered.length > 0) {
|
|
74
|
+
const names = unregistered.map(table => `${table.schemaName}.${table.name} (${mainCollectionId(table)})`).join(', ');
|
|
75
|
+
throw new Error(`Opening the tables of ${schemaNames.join(', ')} registered no collection for ${names}; cannot give those tables an empty collection`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** The collection id the Optimystic vtab stores `table` under: its URI without the `tree://` scheme. */
|
|
79
|
+
function mainCollectionId(table) {
|
|
80
|
+
const explicitUri = table.vtabArgs?.['0'];
|
|
81
|
+
const uri = typeof explicitUri === 'string' && explicitUri !== '' ? explicitUri : defaultCollectionUri(table.schemaName, table.name);
|
|
82
|
+
return (uri.startsWith('tree://') ? uri.slice('tree://'.length) : uri);
|
|
83
|
+
}
|
|
84
|
+
async function syncInventedCollections(registry, excludedMainIds) {
|
|
85
|
+
let committed = 0;
|
|
86
|
+
for (const [id, collection] of registry) {
|
|
87
|
+
if (belongsToExcludedTable(id, excludedMainIds)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// `committedRevision() === undefined` is the invented STATE, which its doc says is safe to branch on.
|
|
91
|
+
if (collection.committedRevision() === undefined && collection.hasUnsyncedChanges()) {
|
|
92
|
+
await collection.sync();
|
|
93
|
+
log('Committed empty collection %s', id);
|
|
94
|
+
committed++;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return committed;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Whether `id` is one of an excluded table's trees: its main collection, or an index or
|
|
101
|
+
* unique-enforcement tree, which the Optimystic plugin keeps at `<main uri>/index/<name>`.
|
|
102
|
+
* Matched by id rather than by "opened here", because the caller's own reads of an excluded
|
|
103
|
+
* table registered it before this step ran.
|
|
104
|
+
*/
|
|
105
|
+
function belongsToExcludedTable(id, excludedMainIds) {
|
|
106
|
+
return excludedMainIds.some(mainId => id === mainId || id.startsWith(`${mainId}/index/`));
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=empty-collections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-collections.js","sourceRoot":"","sources":["../src/empty-collections.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { connectToStrand } from './connect.js';
|
|
2
2
|
export { applyAppSchema } from './compose-strand.js';
|
|
3
|
+
export { createEmptyCollections, type CollectionRegistrySource } from './empty-collections.js';
|
|
3
4
|
export { MIN_CLUSTER_SIZE, COHORT_READ_DEADLINE_MS, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from './cluster-size.js';
|
|
4
5
|
export { wrapStorageWithCache, disposeStorageCache } from './cached-storage.js';
|
|
5
6
|
export type { StrandConnectionOptions, SereusPluginResult, StrandTransactor } from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { connectToStrand } from './connect.js';
|
|
2
2
|
export { applyAppSchema } from './compose-strand.js';
|
|
3
|
+
export { createEmptyCollections } from './empty-collections.js';
|
|
3
4
|
export { MIN_CLUSTER_SIZE, COHORT_READ_DEADLINE_MS, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from './cluster-size.js';
|
|
4
5
|
export { wrapStorageWithCache, disposeStorageCache } from './cached-storage.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAiC,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|