@feltdb/core 0.12.2 → 0.15.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/dist/agent-runtime.d.ts +64 -2
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +121 -11
- package/dist/agent-state.d.ts +48 -0
- package/dist/agent-state.d.ts.map +1 -1
- package/dist/agent-state.js +174 -12
- package/dist/agent.d.ts +10 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +10 -1
- package/dist/build-identity.json +4 -4
- package/dist/cli/commands.js +34 -7
- package/dist/cli/workspace-integration.js +8 -0
- package/dist/collection.d.ts +3 -1
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +30 -8
- package/dist/create/build-identity.json +4 -4
- package/dist/create/cli.js +47 -38
- package/dist/create/create.js +21 -8
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/Cargo.lock +6 -6
- package/dist/create/server-source/Cargo.toml +1 -1
- package/dist/create/server-source/crates/feltdb/src/lib.rs +126 -35
- package/dist/create/server-source/crates/feltdb/src/state_contract.rs +162 -53
- package/dist/create/server-source/crates/feltdb/src/worker_mesh.rs +341 -2
- package/dist/create/server-source/crates/feltdb/src/workload.rs +2094 -126
- package/dist/create/server-source/crates/feltdb/tests/production_readiness_contract.rs +18 -12
- package/dist/create/server-source/crates/feltdb/tests/workload_envelope_contract.rs +17 -5
- package/dist/create/server-source/crates/feltdb-client/Cargo.toml +1 -1
- package/dist/create/server-source/crates/feltdb-server/Cargo.toml +1 -1
- package/dist/create/server-source/crates/feltdb-server/README.md +6 -1
- package/dist/create/server-source/crates/feltdb-server/src/agent_execution.rs +511 -0
- package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +9 -1
- package/dist/create/server-source/crates/feltdb-server/src/auth.rs +113 -25
- package/dist/create/server-source/crates/feltdb-server/src/backup.rs +4 -0
- package/dist/create/server-source/crates/feltdb-server/src/console_accounts.rs +1009 -0
- package/dist/create/server-source/crates/feltdb-server/src/control_authorization.rs +441 -0
- package/dist/create/server-source/crates/feltdb-server/src/identity.rs +68 -6
- package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +355 -23
- package/dist/create/server-source/crates/feltdb-server/src/lib.rs +4 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +1740 -236
- package/dist/create/server-source/crates/feltdb-server/src/redaction.rs +208 -0
- package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +198 -19
- package/dist/create/server-source/crates/feltdb-server/tests/transaction_precondition_contract.rs +403 -0
- package/dist/create/setup-summary.js +40 -0
- package/dist/db.d.ts +91 -10
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +170 -31
- package/dist/deployment.d.ts +19 -0
- package/dist/deployment.d.ts.map +1 -1
- package/dist/deployment.js +38 -2
- package/dist/development-runtime-bridge.d.ts +20 -0
- package/dist/development-runtime-bridge.d.ts.map +1 -1
- package/dist/development-runtime-bridge.js +61 -12
- package/dist/embedded-query.d.ts.map +1 -1
- package/dist/embedded-query.js +5 -4
- package/dist/embedded-transaction.d.ts +8 -4
- package/dist/embedded-transaction.d.ts.map +1 -1
- package/dist/embedded-transaction.js +55 -19
- package/dist/error-codes.d.ts +31 -2
- package/dist/error-codes.d.ts.map +1 -1
- package/dist/error-codes.js +41 -2
- package/dist/feltdb.d.ts +7 -0
- package/dist/feltdb.d.ts.map +1 -1
- package/dist/file-db.d.ts +27 -0
- package/dist/file-db.d.ts.map +1 -1
- package/dist/file-db.js +145 -7
- package/dist/http-client.d.ts +11 -3
- package/dist/http-client.d.ts.map +1 -1
- package/dist/http-client.js +27 -14
- package/dist/http-db.d.ts +40 -1
- package/dist/http-db.d.ts.map +1 -1
- package/dist/http-db.js +285 -58
- package/dist/index.js +1 -1
- package/dist/local-state-lock.d.ts +34 -0
- package/dist/local-state-lock.d.ts.map +1 -0
- package/dist/local-state-lock.js +225 -0
- package/dist/reactive-graph.d.ts +0 -3
- package/dist/reactive-graph.d.ts.map +1 -1
- package/dist/reactive-graph.js +11 -1
- package/dist/runtime-registry.d.ts +7 -2
- package/dist/runtime-registry.d.ts.map +1 -1
- package/dist/runtime-registry.js +2 -2
- package/dist/studio/{KeyManagementPanel-D5FMvvU9.js → KeyManagementPanel-skUNnKRw.js} +36 -29
- package/dist/studio/app.d.ts +8 -1
- package/dist/studio/app.d.ts.map +1 -1
- package/dist/studio/components/KeyManagementPanel.d.ts.map +1 -1
- package/dist/studio/components/KeyManagementPanel.js +1 -1
- package/dist/studio/components/index.js +2 -2
- package/dist/studio/{components-B4eKIUN5.js → components-CJmzntBi.js} +8 -7
- package/dist/studio/control-plane/Data.d.ts.map +1 -1
- package/dist/studio/control-plane/Instance.d.ts +4 -1
- package/dist/studio/control-plane/Instance.d.ts.map +1 -1
- package/dist/studio/control-plane/Operations.d.ts +4 -1
- package/dist/studio/control-plane/Operations.d.ts.map +1 -1
- package/dist/studio/control-plane/index.js +2 -2
- package/dist/studio/control-plane/primitives.d.ts +16 -0
- package/dist/studio/control-plane/primitives.d.ts.map +1 -1
- package/dist/studio/{control-plane-fxMcJn74.js → control-plane-CaBA7Rgv.js} +448 -424
- package/dist/studio/index.d.ts +1 -0
- package/dist/studio/index.d.ts.map +1 -1
- package/dist/studio/index.js +384 -247
- package/dist/studio/navigation.d.ts +57 -0
- package/dist/studio/navigation.d.ts.map +1 -0
- package/dist/studio/studio.css +1 -1
- package/dist/studio/utils/control-plane-api.d.ts +2 -0
- package/dist/studio/utils/control-plane-api.d.ts.map +1 -1
- package/dist/studio/utils/control-plane-api.js +5 -1
- package/dist/studio-app/assets/{feltdb_wasm-BatwwogY.js → feltdb_wasm-BjM1ylL3.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-TseJn2Ax.wasm +0 -0
- package/dist/studio-app/assets/index-1wd0uKua.js +30 -0
- package/dist/studio-app/assets/{index-CiC8VY-a.css → index-vi21oEQa.css} +1 -1
- package/dist/studio-app/index.html +2 -2
- package/dist/transaction.d.ts +27 -11
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +20 -14
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/dist/wasm/package.json +1 -1
- package/dist/workload.d.ts +31 -3
- package/dist/workload.d.ts.map +1 -1
- package/dist/workload.js +28 -3
- package/dist/workspace/local-development-authority.d.ts +19 -0
- package/dist/workspace/local-development-authority.d.ts.map +1 -1
- package/dist/workspace/local-development-authority.js +335 -15
- package/package.json +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-BX0newOr.wasm +0 -0
- package/dist/studio-app/assets/index-DoVvbIay.js +0 -30
|
@@ -42,25 +42,76 @@ function safeBridgeUrl(value) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
let warnedMismatch = false;
|
|
45
|
+
function loopbackOrigin(value) {
|
|
46
|
+
if (!value)
|
|
47
|
+
return undefined;
|
|
48
|
+
try {
|
|
49
|
+
const url = new URL(value);
|
|
50
|
+
const host = ['localhost', '127.0.0.1', '::1', '[::1]'].includes(url.hostname) ? 'loopback' : url.hostname;
|
|
51
|
+
return `${url.protocol}//${host}:${url.port || (url.protocol === 'https:' ? '443' : '80')}`;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** The authority a client is connected to, compared as an endpoint: `localhost` and `127.0.0.1` are one host. */
|
|
58
|
+
export function sameAuthority(left, right) {
|
|
59
|
+
const a = loopbackOrigin(left);
|
|
60
|
+
return a !== undefined && a === loopbackOrigin(right);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Whether a database belongs to a development session: the same namespace, and
|
|
64
|
+
* either the same embedded runtime or a remote connection to the session's own
|
|
65
|
+
* authority. A browser application of a Node.js-authority project is the
|
|
66
|
+
* second case — it runs in the browser but its state is the session's.
|
|
67
|
+
*/
|
|
68
|
+
export function developmentConnectionMatches(session, connection) {
|
|
69
|
+
if (session.namespace !== connection.namespace)
|
|
70
|
+
return false;
|
|
71
|
+
if (connection.runtime === 'remote') {
|
|
72
|
+
if (connection.authorityUrl)
|
|
73
|
+
return sameAuthority(connection.authorityUrl, session.authorityUrl);
|
|
74
|
+
return ['managed', 'self-hosted', 'remote'].includes(session.runtime);
|
|
75
|
+
}
|
|
76
|
+
return session.runtime === connection.runtime;
|
|
77
|
+
}
|
|
45
78
|
/**
|
|
46
79
|
* A development session was supplied but belongs to a different database than
|
|
47
80
|
* the one being opened. Studio would show this app as "Not connected" with no
|
|
48
|
-
* cause, so say what differs once instead of skipping
|
|
81
|
+
* cause, so say what differs, and what to change, once instead of skipping
|
|
82
|
+
* registration silently.
|
|
49
83
|
*/
|
|
50
84
|
function warnSessionMismatch(session, input) {
|
|
51
85
|
if (warnedMismatch)
|
|
52
86
|
return;
|
|
53
87
|
warnedMismatch = true;
|
|
54
|
-
const differences = [
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
88
|
+
const differences = [];
|
|
89
|
+
const advice = [];
|
|
90
|
+
if (session.namespace !== input.namespace) {
|
|
91
|
+
differences.push(`namespace "${input.namespace}" (session expects "${session.namespace}")`);
|
|
92
|
+
advice.push('pass the session namespace to createFeltDB({ namespace })');
|
|
93
|
+
}
|
|
94
|
+
if (input.runtime === 'remote' && input.authorityUrl && !sameAuthority(input.authorityUrl, session.authorityUrl)) {
|
|
95
|
+
differences.push(`authority ${input.authorityUrl} (session authority is ${session.authorityUrl})`);
|
|
96
|
+
advice.push('connect to the session authority (VITE_FELTDB_AUTHORITY_URL) or start `feltdb dev` against this authority');
|
|
97
|
+
}
|
|
98
|
+
else if (session.namespace === input.namespace) {
|
|
99
|
+
differences.push(`runtime "${input.runtime}" (session expects "${session.runtime}")`);
|
|
100
|
+
advice.push(session.runtime === 'browser'
|
|
101
|
+
? 'open the database in the browser runtime'
|
|
102
|
+
: `connect to the session authority with createFeltDB({ namespace, server: { url: ${JSON.stringify(session.authorityUrl)} } })`);
|
|
103
|
+
}
|
|
104
|
+
console.warn(`[feltdb] This database opened with ${differences.join(' and ')}, so it is not registered with the running \`feltdb dev\` session and Studio will report the application as not connected. `
|
|
105
|
+
+ `To connect it, ${advice.join(' and ')}.`);
|
|
60
106
|
}
|
|
61
107
|
/** Internal, optional registration hook called by Core runtime construction. */
|
|
62
108
|
export function attachDevelopmentRuntimeBridge(input) {
|
|
63
109
|
const runtimeInstanceId = randomId();
|
|
110
|
+
const connection = {
|
|
111
|
+
namespace: input.namespace,
|
|
112
|
+
runtime: input.runtime,
|
|
113
|
+
...(input.authorityUrl ? { authorityUrl: input.authorityUrl } : {}),
|
|
114
|
+
};
|
|
64
115
|
let activeSession;
|
|
65
116
|
let heartbeat;
|
|
66
117
|
let flushTimer;
|
|
@@ -74,19 +125,17 @@ export function attachDevelopmentRuntimeBridge(input) {
|
|
|
74
125
|
|| 'application';
|
|
75
126
|
const register = async (candidate) => {
|
|
76
127
|
const session = candidate || configuredSession || processSession();
|
|
77
|
-
const compatibleRuntime = session?.runtime === input.runtime
|
|
78
|
-
|| (input.runtime === 'remote' && ['managed', 'self-hosted', 'remote'].includes(session?.runtime || ''));
|
|
79
128
|
if (!session)
|
|
80
129
|
return;
|
|
81
|
-
if (session
|
|
82
|
-
warnSessionMismatch(session,
|
|
130
|
+
if (!developmentConnectionMatches(session, connection)) {
|
|
131
|
+
warnSessionMismatch(session, connection);
|
|
83
132
|
return;
|
|
84
133
|
}
|
|
85
134
|
const bridgeUrl = safeBridgeUrl(session.bridgeUrl);
|
|
86
135
|
if (!bridgeUrl)
|
|
87
136
|
return;
|
|
88
137
|
activeSession = { ...session, bridgeUrl };
|
|
89
|
-
const registration = { ...activeSession, runtimeInstanceId, applicationId };
|
|
138
|
+
const registration = { ...activeSession, runtimeInstanceId, applicationId, connection };
|
|
90
139
|
try {
|
|
91
140
|
const response = await fetch(`${bridgeUrl}/api/v1/development/runtime/register`, {
|
|
92
141
|
method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(registration),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedded-query.d.ts","sourceRoot":"","sources":["../src/embedded-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"embedded-query.d.ts","sourceRoot":"","sources":["../src/embedded-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAI9E,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAInC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,GAAG,cAAc,GAAG,WAAW,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAgDD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CASrH;AAkCD,kFAAkF;AAClF,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,OAAO,CAAmC;gBAErB,OAAO,EAAE,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIvE,OAAO,IAAI,IAAI;IAMf,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI;IAgCpD,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,IAAI;IAqBZ,OAAO,CAAC,KAAK,EAAE,qBAAqB,GAAG,wBAAwB;IAK/D,OAAO,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,qBAAqB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG;QAAE,KAAK,EAAE,kBAAkB,CAAA;KAAE;IAyErG,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,QAAQ;CAkBjB"}
|
package/dist/embedded-query.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FeltDBErrorCode, FeltDBServiceError } from './error-codes.js';
|
|
1
2
|
const now = () => typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
2
3
|
function compareValue(left, right) {
|
|
3
4
|
if (left === right)
|
|
@@ -78,7 +79,7 @@ function decode(cursor, expectedBinding) {
|
|
|
78
79
|
return value;
|
|
79
80
|
}
|
|
80
81
|
catch {
|
|
81
|
-
throw new
|
|
82
|
+
throw new FeltDBServiceError('INVALID_CURSOR: cursor is malformed or does not match this query', FeltDBErrorCode.INVALID_CURSOR);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
/** Small deterministic planner/executor owned by an embedded storage boundary. */
|
|
@@ -331,7 +332,7 @@ export class EmbeddedQueryEngine {
|
|
|
331
332
|
}
|
|
332
333
|
validate(query) {
|
|
333
334
|
if (!query.collection?.trim() || !Number.isInteger(query.limit) || query.limit < 1 || query.limit > 1_000)
|
|
334
|
-
throw new
|
|
335
|
+
throw new FeltDBServiceError('INVALID_QUERY: collection and a limit between 1 and 1000 are required', 'INVALID_QUERY');
|
|
335
336
|
for (const condition of query.where ?? []) {
|
|
336
337
|
// Every key beside `field` must be exactly one known operator. A stray
|
|
337
338
|
// key — a `semantic` clause misplaced into a condition, or anything
|
|
@@ -340,13 +341,13 @@ export class EmbeddedQueryEngine {
|
|
|
340
341
|
const keys = Object.keys(condition).filter(key => key !== 'field');
|
|
341
342
|
const operators = keys.filter(operator => ['eq', 'neq', 'lt', 'lte', 'gt', 'gte'].includes(operator));
|
|
342
343
|
if (!condition.field || operators.length !== 1 || keys.length !== 1)
|
|
343
|
-
throw new
|
|
344
|
+
throw new FeltDBServiceError('INVALID_QUERY: each condition requires a field and exactly one operator', 'INVALID_QUERY');
|
|
344
345
|
}
|
|
345
346
|
if (query.semantic !== undefined) {
|
|
346
347
|
// Semantic composition runs where the Rust decision primitive runs. This
|
|
347
348
|
// embedded engine has no runtime binding, so it refuses the clause
|
|
348
349
|
// rather than answering the deterministic query in its place.
|
|
349
|
-
throw new
|
|
350
|
+
throw new FeltDBServiceError('SEMANTIC_UNSUPPORTED: this runtime has no semantic runtime binding; semantic query composition is available through the managed authority', 'SEMANTIC_UNSUPPORTED');
|
|
350
351
|
}
|
|
351
352
|
}
|
|
352
353
|
}
|
|
@@ -126,7 +126,7 @@ export type EmbeddedPlan =
|
|
|
126
126
|
kind: 'reject';
|
|
127
127
|
reason: string;
|
|
128
128
|
failure?: ConditionalConflictDetail;
|
|
129
|
-
code?: 'INVALID_REQUEST';
|
|
129
|
+
code?: 'INVALID_REQUEST' | 'CONTRACT_UNSUPPORTED';
|
|
130
130
|
} | {
|
|
131
131
|
kind: 'apply';
|
|
132
132
|
mutations: EmbeddedMutation[];
|
|
@@ -184,8 +184,12 @@ export declare function embeddedDuplicate(request: AtomicTransactionRequest, pla
|
|
|
184
184
|
export declare class EmbeddedTransactionRejected extends Error {
|
|
185
185
|
readonly feltdbCode?: 'PRECONDITION_FAILED';
|
|
186
186
|
readonly feltdbConflict?: ConditionalConflictDetail;
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Set when the request itself was malformed (`INVALID_REQUEST`) or asks for
|
|
189
|
+
* something this runtime cannot evaluate (`CONTRACT_UNSUPPORTED`), as
|
|
190
|
+
* opposed to refused by state.
|
|
191
|
+
*/
|
|
192
|
+
readonly code?: 'INVALID_REQUEST' | 'CONTRACT_UNSUPPORTED';
|
|
193
|
+
constructor(reason: string, failure?: ConditionalConflictDetail, code?: 'INVALID_REQUEST' | 'CONTRACT_UNSUPPORTED');
|
|
190
194
|
}
|
|
191
195
|
//# sourceMappingURL=embedded-transaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedded-transaction.d.ts","sourceRoot":"","sources":["../src/embedded-transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAEV,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EAEzB,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAS1B,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6DAA6D;AAC7D,MAAM,WAAW,wBAAwB;IACvC,yCAAyC;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAC/D;;;;;;;OAOG;IACH,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD;;;;OAIG;IACH,IAAI,CAAC,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACpF;AAED,sEAAsE;AACtE,eAAO,MAAM,0BAA0B,SAAS,CAAC;AAkBjD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GAC/D,MAAM,CAgBR;AAED,wFAAwF;AACxF,wBAAgB,QAAQ,CACtB,OAAO,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACpC,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAS7C;AAED,MAAM,MAAM,YAAY;AACtB;;;;GAIG;AACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,UAAU,GAAG,mBAAmB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AACnG,yEAAyE;GACvE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE;AACtB,sFAAsF;GACpF;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE;AAC1B;;;;;;GAMG;GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,yBAAyB,CAAC;IAAC,IAAI,CAAC,EAAE,iBAAiB,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"embedded-transaction.d.ts","sourceRoot":"","sources":["../src/embedded-transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -95,6 +95,10 @@ export function recordKey(collection, id) {
|
|
|
95
95
|
return `${collection}:${id}`;
|
|
96
96
|
}
|
|
97
97
|
const SEGMENT = /^[A-Za-z0-9._-]{1,128}$/;
|
|
98
|
+
/** The version a guard fences on, whichever spelling supplied it. */
|
|
99
|
+
function fencedVersion(guard) {
|
|
100
|
+
return guard.expectedVersion ?? guard.ifVersion;
|
|
101
|
+
}
|
|
98
102
|
/**
|
|
99
103
|
* Whether the request is well-formed, judged without any stored state.
|
|
100
104
|
*
|
|
@@ -109,6 +113,11 @@ function structuralRefusal(request) {
|
|
|
109
113
|
if (request.operations.length === 0)
|
|
110
114
|
return invalid('a transaction requires at least one operation');
|
|
111
115
|
const seen = new Set();
|
|
116
|
+
for (const guarded of [...request.operations, ...(request.preconditions ?? [])]) {
|
|
117
|
+
if (guarded.ifVersion !== undefined && guarded.expectedVersion !== undefined && guarded.ifVersion !== guarded.expectedVersion) {
|
|
118
|
+
return invalid(`${guarded.collection}:${guarded.id} supplies ifVersion ${guarded.ifVersion} and expectedVersion ${guarded.expectedVersion}; they are the same predicate`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
112
121
|
for (const operation of request.operations) {
|
|
113
122
|
if (!SEGMENT.test(operation.collection) || !SEGMENT.test(operation.id)) {
|
|
114
123
|
return invalid(`invalid collection or id: ${operation.collection}:${operation.id}`);
|
|
@@ -195,16 +204,24 @@ export function decideTransaction(request, state, digest) {
|
|
|
195
204
|
}
|
|
196
205
|
// Preconditions first, before any operation is staged, so a failure cannot
|
|
197
206
|
// leave a prefix of the transaction decided.
|
|
207
|
+
//
|
|
208
|
+
// `ifVersion` is the public spelling of `expectedVersion` and reaches this
|
|
209
|
+
// boundary unnormalised from callers below `db.transaction` (collections,
|
|
210
|
+
// agent state, composition). It is the same predicate, so it is evaluated
|
|
211
|
+
// here rather than counted as "constrains something" and then skipped.
|
|
198
212
|
const guards = [
|
|
199
|
-
...(request.preconditions ?? []).map(condition => ({
|
|
213
|
+
...(request.preconditions ?? []).map(condition => ({
|
|
214
|
+
...condition,
|
|
215
|
+
expectedVersion: fencedVersion(condition),
|
|
216
|
+
})),
|
|
200
217
|
...request.operations
|
|
201
|
-
.filter(operation => operation
|
|
218
|
+
.filter(operation => fencedVersion(operation) !== undefined
|
|
202
219
|
|| operation.expectedEpoch !== undefined
|
|
203
220
|
|| operation.expectedLeaseId !== undefined)
|
|
204
221
|
.map(operation => ({
|
|
205
222
|
collection: operation.collection,
|
|
206
223
|
id: operation.id,
|
|
207
|
-
expectedVersion: operation
|
|
224
|
+
expectedVersion: fencedVersion(operation),
|
|
208
225
|
expectedEpoch: operation.expectedEpoch,
|
|
209
226
|
expectedLeaseId: operation.expectedLeaseId,
|
|
210
227
|
})),
|
|
@@ -214,11 +231,12 @@ export function decideTransaction(request, state, digest) {
|
|
|
214
231
|
kind: 'reject',
|
|
215
232
|
reason: 'this runtime cannot evaluate transaction preconditions, so it refuses the '
|
|
216
233
|
+ 'transaction rather than committing it unconditionally',
|
|
234
|
+
code: 'CONTRACT_UNSUPPORTED',
|
|
217
235
|
};
|
|
218
236
|
}
|
|
219
237
|
for (const guard of guards) {
|
|
220
238
|
if (!SEGMENT.test(guard.collection) || !SEGMENT.test(String(guard.id))) {
|
|
221
|
-
return { kind: 'reject', reason: `invalid collection or id: ${guard.collection}:${guard.id}
|
|
239
|
+
return { kind: 'reject', reason: `invalid collection or id: ${guard.collection}:${guard.id}`, code: 'INVALID_REQUEST' };
|
|
222
240
|
}
|
|
223
241
|
const constrains = guard.requireAbsent === true
|
|
224
242
|
|| guard.expectedVersion !== undefined
|
|
@@ -228,6 +246,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
228
246
|
return {
|
|
229
247
|
kind: 'reject',
|
|
230
248
|
reason: `precondition on ${guard.collection}:${guard.id} constrains nothing`,
|
|
249
|
+
code: 'INVALID_REQUEST',
|
|
231
250
|
};
|
|
232
251
|
}
|
|
233
252
|
const key = recordKey(guard.collection, String(guard.id));
|
|
@@ -237,7 +256,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
237
256
|
return {
|
|
238
257
|
kind: 'reject',
|
|
239
258
|
reason: `PRECONDITION_FAILED:${key}:record already exists`,
|
|
240
|
-
failure: { predicate: 'present', collection: guard.collection, key },
|
|
259
|
+
failure: { predicate: 'present', collection: guard.collection, id: String(guard.id), key },
|
|
241
260
|
};
|
|
242
261
|
}
|
|
243
262
|
continue;
|
|
@@ -246,7 +265,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
246
265
|
return {
|
|
247
266
|
kind: 'reject',
|
|
248
267
|
reason: `PRECONDITION_FAILED:${key}:record does not exist`,
|
|
249
|
-
failure: { predicate: 'missing', collection: guard.collection, key },
|
|
268
|
+
failure: { predicate: 'missing', collection: guard.collection, id: String(guard.id), key },
|
|
250
269
|
};
|
|
251
270
|
}
|
|
252
271
|
if (guard.expectedVersion !== undefined) {
|
|
@@ -258,6 +277,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
258
277
|
failure: {
|
|
259
278
|
predicate: 'version',
|
|
260
279
|
collection: guard.collection,
|
|
280
|
+
id: String(guard.id),
|
|
261
281
|
key,
|
|
262
282
|
expected: guard.expectedVersion,
|
|
263
283
|
actual,
|
|
@@ -275,6 +295,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
275
295
|
failure: {
|
|
276
296
|
predicate: 'epoch',
|
|
277
297
|
collection: guard.collection,
|
|
298
|
+
id: String(guard.id),
|
|
278
299
|
key,
|
|
279
300
|
expected: guard.expectedEpoch,
|
|
280
301
|
actual,
|
|
@@ -293,6 +314,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
293
314
|
failure: {
|
|
294
315
|
predicate: 'lease',
|
|
295
316
|
collection: guard.collection,
|
|
317
|
+
id: String(guard.id),
|
|
296
318
|
key,
|
|
297
319
|
expected: guard.expectedLeaseId,
|
|
298
320
|
actual: held ?? null,
|
|
@@ -310,18 +332,19 @@ export function decideTransaction(request, state, digest) {
|
|
|
310
332
|
kind: 'reject',
|
|
311
333
|
reason: 'this runtime cannot evaluate read-basis fences inside its commit boundary, so it refuses the '
|
|
312
334
|
+ 'transaction rather than committing it unfenced',
|
|
335
|
+
code: 'CONTRACT_UNSUPPORTED',
|
|
313
336
|
};
|
|
314
337
|
}
|
|
315
338
|
for (const fence of fences) {
|
|
316
339
|
if (typeof fence?.token !== 'string' || !fence.token.startsWith(EMBEDDED_READ_BASIS_PREFIX)) {
|
|
317
|
-
return { kind: 'reject', reason: 'a read basis was not issued by this authority' };
|
|
340
|
+
return { kind: 'reject', reason: 'a read basis was not issued by this authority', code: 'INVALID_REQUEST' };
|
|
318
341
|
}
|
|
319
342
|
let actual;
|
|
320
343
|
try {
|
|
321
344
|
actual = readBasisToken(fence.reads, { read: state.read, scan: state.scan });
|
|
322
345
|
}
|
|
323
346
|
catch (error) {
|
|
324
|
-
return { kind: 'reject', reason: `invalid read basis: ${error instanceof Error ? error.message : String(error)}
|
|
347
|
+
return { kind: 'reject', reason: `invalid read basis: ${error instanceof Error ? error.message : String(error)}`, code: 'INVALID_REQUEST' };
|
|
325
348
|
}
|
|
326
349
|
if (actual !== fence.token) {
|
|
327
350
|
const first = normaliseReadSet(fence.reads);
|
|
@@ -345,6 +368,7 @@ export function decideTransaction(request, state, digest) {
|
|
|
345
368
|
return {
|
|
346
369
|
kind: 'reject',
|
|
347
370
|
reason: `invalid collection or id: ${operation.collection}:${operation.id}`,
|
|
371
|
+
code: 'INVALID_REQUEST',
|
|
348
372
|
};
|
|
349
373
|
}
|
|
350
374
|
const key = recordKey(operation.collection, operation.id);
|
|
@@ -352,30 +376,38 @@ export function decideTransaction(request, state, digest) {
|
|
|
352
376
|
return {
|
|
353
377
|
kind: 'reject',
|
|
354
378
|
reason: `PRECONDITION_FAILED:${key}:record already exists`,
|
|
355
|
-
failure: { predicate: 'present', collection: operation.collection, key },
|
|
379
|
+
failure: { predicate: 'present', collection: operation.collection, id: operation.id, key },
|
|
356
380
|
};
|
|
357
381
|
}
|
|
358
382
|
// A requireAbsent create begins the authority-owned version lifecycle at
|
|
359
|
-
// 1. A write fenced by expectedVersion
|
|
360
|
-
//
|
|
361
|
-
//
|
|
362
|
-
//
|
|
383
|
+
// 1. A write fenced by expectedVersion -- on the operation itself or by a
|
|
384
|
+
// transaction-level precondition on the same record -- is validated at N
|
|
385
|
+
// and written at N + 1. Both are resolved in the same decision the runtime
|
|
386
|
+
// applies atomically. An unconditional write remains verbatim, and a
|
|
387
|
+
// delete has no record left to carry a version.
|
|
388
|
+
//
|
|
389
|
+
// Where the fence is declared does not matter, and must not: a guard
|
|
390
|
+
// `preconditions: [{ A, ifVersion: N }]` beside a write of A that left the
|
|
391
|
+
// version alone would let a second transaction guarded on N commit after
|
|
392
|
+
// the first, which is the exclusive progression the guard exists to
|
|
393
|
+
// provide. The Rust authority applies the same rule.
|
|
363
394
|
//
|
|
364
395
|
// The value the caller supplied for __version is replaced rather than
|
|
365
396
|
// honoured, because a caller that computes a different next version must
|
|
366
397
|
// not be able to install it.
|
|
367
398
|
// See docs/architecture/transaction-version-contract.md.
|
|
399
|
+
const sameRecord = (guard) => guard.collection === operation.collection
|
|
400
|
+
&& String(guard.id) === operation.id;
|
|
368
401
|
const guardedCreate = operation.requireAbsent === true
|
|
369
|
-
|| guards.some(guard => guard.requireAbsent === true
|
|
370
|
-
|
|
371
|
-
&& String(guard.id) === operation.id);
|
|
402
|
+
|| guards.some(guard => guard.requireAbsent === true && sameRecord(guard));
|
|
403
|
+
const fencedAt = guards.find(guard => guard.expectedVersion !== undefined && sameRecord(guard))?.expectedVersion;
|
|
372
404
|
const value = operation.value === undefined
|
|
373
405
|
? undefined
|
|
374
406
|
: guardedCreate
|
|
375
407
|
? { ...operation.value, id: operation.id, __version: 1 }
|
|
376
|
-
:
|
|
408
|
+
: fencedAt === undefined
|
|
377
409
|
? { ...operation.value, id: operation.id }
|
|
378
|
-
: { ...operation.value, id: operation.id, __version:
|
|
410
|
+
: { ...operation.value, id: operation.id, __version: fencedAt + 1 };
|
|
379
411
|
mutations.push({
|
|
380
412
|
key,
|
|
381
413
|
collection: operation.collection,
|
|
@@ -437,7 +469,11 @@ export function embeddedDuplicate(request, plan) {
|
|
|
437
469
|
export class EmbeddedTransactionRejected extends Error {
|
|
438
470
|
feltdbCode;
|
|
439
471
|
feltdbConflict;
|
|
440
|
-
/**
|
|
472
|
+
/**
|
|
473
|
+
* Set when the request itself was malformed (`INVALID_REQUEST`) or asks for
|
|
474
|
+
* something this runtime cannot evaluate (`CONTRACT_UNSUPPORTED`), as
|
|
475
|
+
* opposed to refused by state.
|
|
476
|
+
*/
|
|
441
477
|
code;
|
|
442
478
|
constructor(reason, failure, code) {
|
|
443
479
|
super(reason);
|
package/dist/error-codes.d.ts
CHANGED
|
@@ -53,13 +53,42 @@ export declare enum FeltDBErrorCode {
|
|
|
53
53
|
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",
|
|
54
54
|
AUTHORITY_SCOPE_REQUIRED = "AUTHORITY_SCOPE_REQUIRED",
|
|
55
55
|
AUTHORITY_SCOPE_INVALID = "AUTHORITY_SCOPE_INVALID",
|
|
56
|
-
AUTHORITY_SCOPE_MISMATCH = "AUTHORITY_SCOPE_MISMATCH"
|
|
56
|
+
AUTHORITY_SCOPE_MISMATCH = "AUTHORITY_SCOPE_MISMATCH",
|
|
57
|
+
/** A local state directory is open exclusively by another live process. */
|
|
58
|
+
STATE_LOCKED = "STATE_LOCKED",
|
|
59
|
+
/** Stored content no longer hashes to its address. The bytes were not returned. */
|
|
60
|
+
CONTENT_INTEGRITY_FAILURE = "CONTENT_INTEGRITY_FAILURE"
|
|
57
61
|
}
|
|
58
62
|
export declare class FeltDBServiceError extends Error {
|
|
59
63
|
readonly code: FeltDBErrorCode | string;
|
|
60
64
|
readonly requestId?: string | undefined;
|
|
61
65
|
readonly status?: number | undefined;
|
|
62
|
-
|
|
66
|
+
/** The authority's structured error body, when it answered with one. */
|
|
67
|
+
readonly body?: Record<string, unknown>;
|
|
68
|
+
constructor(message: string, code: FeltDBErrorCode | string, requestId?: string | undefined, status?: number | undefined, body?: Record<string, unknown>);
|
|
69
|
+
/** The body's structured `details`, when it carried any (e.g. a reused idempotency key's reason). */
|
|
70
|
+
get details(): Record<string, unknown> | undefined;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The local file runtime's state directory is held exclusively by another
|
|
74
|
+
* process. Nothing was opened, read, or modified.
|
|
75
|
+
*
|
|
76
|
+
* `owner` is what the lock file records about its holder. Close the other
|
|
77
|
+
* process, or, if it is gone and its lock could not be judged stale (another
|
|
78
|
+
* host, an unreadable lock), remove `lockPath` by hand.
|
|
79
|
+
*/
|
|
80
|
+
export declare class LocalStateLockedError extends FeltDBServiceError {
|
|
81
|
+
readonly lockPath: string;
|
|
82
|
+
readonly owner: {
|
|
83
|
+
pid?: number;
|
|
84
|
+
host?: string;
|
|
85
|
+
acquiredAt?: string;
|
|
86
|
+
};
|
|
87
|
+
constructor(lockPath: string, owner: {
|
|
88
|
+
pid?: number;
|
|
89
|
+
host?: string;
|
|
90
|
+
acquiredAt?: string;
|
|
91
|
+
}, detail?: string);
|
|
63
92
|
}
|
|
64
93
|
/**
|
|
65
94
|
* Error response structure that all FeltDB APIs must return
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-codes.d.ts","sourceRoot":"","sources":["../src/error-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,oBAAY,eAAe;IACzB,eAAe,oBAAoB;IACnC,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;IACjC,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;IACzC,gBAAgB,qBAAqB;IACrC,oBAAoB,yBAAyB;IAC7C,6BAA6B;IAC7B,EAAE,OAAO;IAET,wEAAwE;IACxE,QAAQ,aAAa;IAErB,2DAA2D;IAC3D,mBAAmB,wBAAwB;IAE3C,gEAAgE;IAChE,QAAQ,aAAa;IAErB,6DAA6D;IAC7D,cAAc,mBAAmB;IACjC,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,gBAAgB,qBAAqB;IACrC,oBAAoB,yBAAyB;IAC7C,gFAAgF;IAChF,wBAAwB,6BAA6B;IACrD;sEACkE;IAClE,sBAAsB,2BAA2B;IACjD,aAAa,kBAAkB;IAC/B,oBAAoB,yBAAyB;IAC7C,kBAAkB,uBAAuB;IACzC,eAAe,oBAAoB;IACnC,oBAAoB,yBAAyB;IAC7C,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;IAC3C,wBAAwB,6BAA6B;IACrD,uBAAuB,4BAA4B;IACnD,wBAAwB,6BAA6B;
|
|
1
|
+
{"version":3,"file":"error-codes.d.ts","sourceRoot":"","sources":["../src/error-codes.ts"],"names":[],"mappings":"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"}
|
package/dist/error-codes.js
CHANGED
|
@@ -55,17 +55,53 @@ export var FeltDBErrorCode;
|
|
|
55
55
|
FeltDBErrorCode["AUTHORITY_SCOPE_REQUIRED"] = "AUTHORITY_SCOPE_REQUIRED";
|
|
56
56
|
FeltDBErrorCode["AUTHORITY_SCOPE_INVALID"] = "AUTHORITY_SCOPE_INVALID";
|
|
57
57
|
FeltDBErrorCode["AUTHORITY_SCOPE_MISMATCH"] = "AUTHORITY_SCOPE_MISMATCH";
|
|
58
|
+
/** A local state directory is open exclusively by another live process. */
|
|
59
|
+
FeltDBErrorCode["STATE_LOCKED"] = "STATE_LOCKED";
|
|
60
|
+
/** Stored content no longer hashes to its address. The bytes were not returned. */
|
|
61
|
+
FeltDBErrorCode["CONTENT_INTEGRITY_FAILURE"] = "CONTENT_INTEGRITY_FAILURE";
|
|
58
62
|
})(FeltDBErrorCode || (FeltDBErrorCode = {}));
|
|
59
63
|
export class FeltDBServiceError extends Error {
|
|
60
64
|
code;
|
|
61
65
|
requestId;
|
|
62
66
|
status;
|
|
63
|
-
|
|
67
|
+
/** The authority's structured error body, when it answered with one. */
|
|
68
|
+
body;
|
|
69
|
+
constructor(message, code, requestId, status, body) {
|
|
64
70
|
super(message);
|
|
65
71
|
this.code = code;
|
|
66
72
|
this.requestId = requestId;
|
|
67
73
|
this.status = status;
|
|
68
74
|
this.name = 'FeltDBServiceError';
|
|
75
|
+
if (body !== undefined)
|
|
76
|
+
this.body = body;
|
|
77
|
+
}
|
|
78
|
+
/** The body's structured `details`, when it carried any (e.g. a reused idempotency key's reason). */
|
|
79
|
+
get details() {
|
|
80
|
+
const details = this.body?.details;
|
|
81
|
+
return details && typeof details === 'object' && !Array.isArray(details) ? details : undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The local file runtime's state directory is held exclusively by another
|
|
86
|
+
* process. Nothing was opened, read, or modified.
|
|
87
|
+
*
|
|
88
|
+
* `owner` is what the lock file records about its holder. Close the other
|
|
89
|
+
* process, or, if it is gone and its lock could not be judged stale (another
|
|
90
|
+
* host, an unreadable lock), remove `lockPath` by hand.
|
|
91
|
+
*/
|
|
92
|
+
export class LocalStateLockedError extends FeltDBServiceError {
|
|
93
|
+
lockPath;
|
|
94
|
+
owner;
|
|
95
|
+
constructor(lockPath, owner, detail) {
|
|
96
|
+
super(`STATE_LOCKED: ${lockPath.replace(/[\\/][^\\/]+$/, '')} is open exclusively by `
|
|
97
|
+
+ `${owner.pid === undefined ? 'another process' : `process ${owner.pid}`}`
|
|
98
|
+
+ `${owner.host ? ` on ${owner.host}` : ''}${owner.acquiredAt ? ` since ${owner.acquiredAt}` : ''}. `
|
|
99
|
+
+ (detail ? `${detail} ` : '')
|
|
100
|
+
+ 'Close that process first, or open with createFeltDB({ path, access: \'shared\' }) if several '
|
|
101
|
+
+ 'processes are meant to share this state.', FeltDBErrorCode.STATE_LOCKED);
|
|
102
|
+
this.lockPath = lockPath;
|
|
103
|
+
this.owner = owner;
|
|
104
|
+
this.name = 'LocalStateLockedError';
|
|
69
105
|
}
|
|
70
106
|
}
|
|
71
107
|
/**
|
|
@@ -81,7 +117,10 @@ export function classifyError(code) {
|
|
|
81
117
|
return 'retryable';
|
|
82
118
|
if (code === FeltDBErrorCode.CONFLICT || code === FeltDBErrorCode.VERSION_CONFLICT
|
|
83
119
|
|| code === FeltDBErrorCode.IDEMPOTENCY_CONFLICT
|
|
84
|
-
|| code === FeltDBErrorCode.COMMIT_OUTCOME_UNKNOWN
|
|
120
|
+
|| code === FeltDBErrorCode.COMMIT_OUTCOME_UNKNOWN
|
|
121
|
+
// A commit the authority could not make durable has an unknown outcome:
|
|
122
|
+
// reconcile by retrying with the same transaction id, never by assuming.
|
|
123
|
+
|| code === FeltDBErrorCode.DURABILITY_FAILURE)
|
|
85
124
|
return 'requires_reconciliation';
|
|
86
125
|
if (code === FeltDBErrorCode.PRECONDITION_FAILED
|
|
87
126
|
|| code === FeltDBErrorCode.VALIDATION_ERROR
|
package/dist/feltdb.d.ts
CHANGED
|
@@ -67,6 +67,13 @@ export interface JsDb {
|
|
|
67
67
|
delete?(key: string): any | Promise<any>;
|
|
68
68
|
/** Subscribe to runtime-originated changes, including remote mutations. */
|
|
69
69
|
subscribe_changes?(callback: (collection: string) => void, collection?: string): () => void;
|
|
70
|
+
/** Content-addressed immutable bytes (server and local file runtimes). */
|
|
71
|
+
storeContent?(content: Uint8Array): Promise<{
|
|
72
|
+
hash: string;
|
|
73
|
+
bytes: number;
|
|
74
|
+
ref: string;
|
|
75
|
+
}>;
|
|
76
|
+
acquireContent?(hash: string): Promise<Uint8Array | null>;
|
|
70
77
|
close?(): void | Promise<void>;
|
|
71
78
|
/**
|
|
72
79
|
* Get capability records
|
package/dist/feltdb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feltdb.d.ts","sourceRoot":"","sources":["../src/feltdb.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"feltdb.d.ts","sourceRoot":"","sources":["../src/feltdb.ts"],"names":[],"mappings":"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"}
|
package/dist/file-db.d.ts
CHANGED
|
@@ -57,6 +57,15 @@ export interface FileJsDbOptions {
|
|
|
57
57
|
};
|
|
58
58
|
/** Collect persistence timings. Also enabled by `FELTDB_PERSISTENCE_PROFILE=1`. */
|
|
59
59
|
profile?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* `shared` (the default for a directly constructed `FileJsDb`): any number
|
|
62
|
+
* of processes may open the directory; each commit is serialized by
|
|
63
|
+
* `state.lock`. `exclusive` (the default of `createFeltDB({ path })`): this
|
|
64
|
+
* process takes `owner.lock` at open and another process opening the same
|
|
65
|
+
* directory exclusively *or shared* is refused with `LocalStateLockedError`
|
|
66
|
+
* until `close()` or process exit. Handles in one process share the lock.
|
|
67
|
+
*/
|
|
68
|
+
access?: 'shared' | 'exclusive';
|
|
60
69
|
}
|
|
61
70
|
export interface PersistenceStatus {
|
|
62
71
|
format: 'none' | 'legacy-snapshot' | 'snapshot+journal';
|
|
@@ -91,7 +100,16 @@ export declare class FileJsDb implements JsDb {
|
|
|
91
100
|
private readonly profiler;
|
|
92
101
|
private readonly compaction;
|
|
93
102
|
private compactionScheduled;
|
|
103
|
+
private releaseOwnerLock;
|
|
104
|
+
/** How this handle opened its directory. */
|
|
105
|
+
readonly access: 'shared' | 'exclusive';
|
|
94
106
|
constructor(path: string, options?: FileJsDbOptions);
|
|
107
|
+
/**
|
|
108
|
+
* A shared open still respects an exclusive owner in another process: a
|
|
109
|
+
* process that asked for exclusive access must not find a second writer.
|
|
110
|
+
* Probing takes no lock of its own.
|
|
111
|
+
*/
|
|
112
|
+
private assertNotHeldExclusively;
|
|
95
113
|
private journalPath;
|
|
96
114
|
private snapshotKey;
|
|
97
115
|
private parseSnapshot;
|
|
@@ -283,6 +301,15 @@ export declare class FileJsDb implements JsDb {
|
|
|
283
301
|
conflictCode?: string;
|
|
284
302
|
item?: any;
|
|
285
303
|
}>;
|
|
304
|
+
private contentDirectory;
|
|
305
|
+
private static sha256;
|
|
306
|
+
storeContent(content: Uint8Array): Promise<{
|
|
307
|
+
hash: string;
|
|
308
|
+
bytes: number;
|
|
309
|
+
ref: string;
|
|
310
|
+
}>;
|
|
311
|
+
acquireContent(hash: string): Promise<Uint8Array | null>;
|
|
312
|
+
private fsyncDirectory;
|
|
286
313
|
close(): void;
|
|
287
314
|
}
|
|
288
315
|
//# sourceMappingURL=file-db.d.ts.map
|