@feltdb/core 0.12.0 → 0.12.2
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-state.d.ts +489 -0
- package/dist/agent-state.d.ts.map +1 -0
- package/dist/agent-state.js +993 -0
- package/dist/build-identity.json +28 -0
- package/dist/cli/commands.js +88 -43
- package/dist/collection.d.ts +41 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +116 -47
- package/dist/composition.d.ts.map +1 -1
- package/dist/composition.js +11 -1
- package/dist/create/build-identity.json +28 -0
- package/dist/create/cli.js +3 -3
- package/dist/create/create.js +17 -19
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/Cargo.lock +18 -3
- package/dist/create/server-source/Cargo.toml +4 -2
- package/dist/create/server-source/crates/feltdb/Cargo.toml +20 -0
- package/dist/create/server-source/crates/feltdb/LICENSE +21 -0
- package/dist/create/server-source/crates/feltdb/README.md +75 -0
- package/dist/create/server-source/crates/feltdb/src/agent_state.rs +320 -0
- package/dist/create/server-source/crates/feltdb/src/agent_transition_contract.rs +1545 -0
- package/dist/create/server-source/crates/feltdb/src/authority.rs +145 -15
- package/dist/create/server-source/crates/feltdb/src/lib.rs +238 -23
- package/dist/create/server-source/crates/feltdb/src/query_performance.rs +4 -1
- package/dist/create/server-source/crates/feltdb/src/state_model.rs +850 -155
- package/dist/create/server-source/crates/feltdb/tests/agent_state_native.rs +1188 -0
- package/dist/create/server-source/crates/feltdb/tests/agent_transition_contract_conformance.rs +2884 -0
- package/dist/create/server-source/crates/feltdb/tests/authority_transaction_identity.rs +534 -0
- package/dist/create/server-source/crates/feltdb/tests/fixtures/agent_transition_corpus.json +23340 -0
- package/dist/create/server-source/crates/feltdb/tests/generalized_version_control_substrate_completion.rs +31 -13
- package/dist/create/server-source/crates/feltdb/tests/state_ref_authority.rs +918 -0
- package/dist/create/server-source/crates/feltdb/tests/workload_envelope_contract.rs +15 -2
- package/dist/create/server-source/crates/feltdb-client/Cargo.toml +29 -0
- package/dist/create/server-source/crates/feltdb-client/LICENSE +21 -0
- package/dist/create/server-source/crates/feltdb-client/README.md +70 -0
- package/dist/create/server-source/crates/feltdb-client/src/application.rs +527 -0
- package/dist/create/server-source/crates/feltdb-client/src/authority.rs +679 -0
- package/dist/create/server-source/crates/feltdb-client/src/control.rs +292 -0
- package/dist/create/server-source/crates/feltdb-client/src/error.rs +227 -0
- package/dist/create/server-source/crates/feltdb-client/src/events.rs +146 -0
- package/dist/create/server-source/crates/feltdb-client/src/lib.rs +466 -0
- package/dist/create/server-source/crates/feltdb-client/tests/fixtures/README.md +4 -0
- package/dist/create/server-source/crates/feltdb-client/tests/fixtures/private-ca.pem +20 -0
- package/dist/create/server-source/crates/feltdb-client/tests/fixtures/server-key.pem +28 -0
- package/dist/create/server-source/crates/feltdb-client/tests/fixtures/server.pem +20 -0
- package/dist/create/server-source/crates/feltdb-client/tests/private_ca.rs +95 -0
- package/dist/create/server-source/crates/feltdb-server/Cargo.toml +24 -1
- package/dist/create/server-source/crates/feltdb-server/LICENSE +21 -0
- package/dist/create/server-source/crates/feltdb-server/README.md +12 -1
- package/dist/create/server-source/crates/feltdb-server/benches/query_shape_observer.rs +136 -0
- package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +3 -0
- package/dist/create/server-source/crates/feltdb-server/src/backup.rs +6 -2
- package/dist/create/server-source/crates/feltdb-server/src/lib.rs +21 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +75 -8
- package/dist/create/server-source/crates/feltdb-server/src/query_shape.rs +1137 -0
- package/dist/create/server-source/crates/feltdb-server/tests/fixtures/query-shape-trace.expected.json +300 -0
- package/dist/create/server-source/crates/feltdb-server/tests/fixtures/query-shape-trace.json +25 -0
- package/dist/create/server-source/crates/feltdb-server/tests/query_shape_trace.rs +128 -0
- package/dist/create/server-source/crates/feltdb-server/tests/rust_client.rs +683 -0
- package/dist/create/server-source/crates/feltdb-wasm/Cargo.toml +3 -1
- package/dist/create/template/default-project/README.md +12 -7
- package/dist/create/template/default-project/src/pages/Dashboard.tsx +1 -1
- package/dist/create/template/dot-feltdb-README.md +3 -3
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +43 -17
- package/dist/development-runtime-bridge.d.ts.map +1 -1
- package/dist/development-runtime-bridge.js +22 -1
- package/dist/embedded-transaction.d.ts +75 -8
- package/dist/embedded-transaction.d.ts.map +1 -1
- package/dist/embedded-transaction.js +124 -18
- package/dist/error-codes.d.ts +2 -0
- package/dist/error-codes.d.ts.map +1 -1
- package/dist/error-codes.js +2 -0
- package/dist/feltdb.d.ts +1 -11
- package/dist/feltdb.d.ts.map +1 -1
- package/dist/file-db.d.ts +6 -0
- package/dist/file-db.d.ts.map +1 -1
- package/dist/file-db.js +43 -11
- package/dist/index-core.d.ts +1 -0
- package/dist/index-core.d.ts.map +1 -1
- package/dist/index-core.js +1 -0
- package/dist/indexeddb-db.d.ts.map +1 -1
- package/dist/indexeddb-db.js +65 -41
- package/dist/memory-db.d.ts.map +1 -1
- package/dist/memory-db.js +29 -8
- package/dist/studio/{KeyManagementPanel-DZuSeWBK.js → KeyManagementPanel-D5FMvvU9.js} +1 -0
- package/dist/studio/app.d.ts.map +1 -1
- package/dist/studio/components/GlobalSearch.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/RouteErrorBoundary.d.ts +5 -0
- package/dist/studio/components/RouteErrorBoundary.d.ts.map +1 -0
- package/dist/studio/components/index.js +2 -2
- package/dist/studio/{components-BHTKlUgT.js → components-B4eKIUN5.js} +3 -2
- package/dist/studio/control-plane/Agents.d.ts.map +1 -1
- package/dist/studio/control-plane/Data.d.ts.map +1 -1
- package/dist/studio/control-plane/Instance.d.ts.map +1 -1
- package/dist/studio/control-plane/Operations.d.ts.map +1 -1
- package/dist/studio/control-plane/Overview.d.ts.map +1 -1
- package/dist/studio/control-plane/Schema.d.ts.map +1 -1
- package/dist/studio/control-plane/State.d.ts +11 -0
- package/dist/studio/control-plane/State.d.ts.map +1 -1
- package/dist/studio/control-plane/context.d.ts +4 -1
- package/dist/studio/control-plane/context.d.ts.map +1 -1
- package/dist/studio/control-plane/index.d.ts +1 -1
- package/dist/studio/control-plane/index.d.ts.map +1 -1
- package/dist/studio/control-plane/index.js +2 -2
- package/dist/studio/control-plane/primitives.d.ts +22 -2
- package/dist/studio/control-plane/primitives.d.ts.map +1 -1
- package/dist/studio/control-plane-fxMcJn74.js +4173 -0
- package/dist/studio/index.js +307 -235
- package/dist/studio/studio.css +1 -1
- package/dist/studio/utils/control-plane-api.d.ts.map +1 -1
- package/dist/studio/utils/control-plane-api.js +4 -3
- package/dist/studio/utils/service-api.d.ts.map +1 -1
- package/dist/studio/utils/service-api.js +5 -4
- package/dist/studio-app/assets/{feltdb_wasm-DYfWAV0E.js → feltdb_wasm-BatwwogY.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-BX0newOr.wasm +0 -0
- package/dist/studio-app/assets/index-CiC8VY-a.css +1 -0
- package/dist/studio-app/assets/index-DoVvbIay.js +30 -0
- package/dist/studio-app/index.html +2 -2
- package/dist/telemetry.d.ts +1 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +4 -3
- package/dist/transaction-identity.d.ts +62 -0
- package/dist/transaction-identity.d.ts.map +1 -0
- package/dist/transaction-identity.js +138 -0
- package/dist/transaction.d.ts +50 -5
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +28 -0
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/dist/wasm/package.json +1 -1
- package/package.json +2 -2
- package/dist/create/server-source/crates/feltdb-wasm/test.db +0 -0
- package/dist/studio/control-plane-DP8ljTDO.js +0 -3207
- package/dist/studio-app/assets/feltdb_wasm_bg-DHiOUhoQ.wasm +0 -0
- package/dist/studio-app/assets/index-6f6KVx5R.js +0 -30
- package/dist/studio-app/assets/index-BrsF-kWL.css +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-
|
|
2
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-DoVvbIay.js"></script>
|
|
2
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CiC8VY-a.css">
|
|
3
3
|
</head><body><div id="root"></div></body></html>
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Privacy-preserving, anonymous telemetry for adoption analytics.
|
|
5
5
|
* No source code, project names, filesystem paths, or PII collected.
|
|
6
|
+
* Disabled by default; opt in with FELTDB_TELEMETRY=1.
|
|
6
7
|
* Fail-open: telemetry failures never affect FeltDB operation.
|
|
7
8
|
*/
|
|
8
9
|
/**
|
package/dist/telemetry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4CH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,YAAY,GACZ,OAAO,GACP,OAAO,GACP,MAAM,GACN,iBAAiB,GACjB,qBAAqB,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AA8CD;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAM;IAChC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAA8B;gBAEjC,WAAW,GAAE,MAAgB;IAczC;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI;IA6BzC;;OAEG;YACW,KAAK;IAqBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;OAGG;YACW,UAAU;IA6BxB;;OAEG;IACH,OAAO,CAAC,KAAK;IAkBb;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,OAAO,IAAI,IAAI;IASf;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAKlC;AAOD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,eAAe,CAKxE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAEjE"}
|
package/dist/telemetry.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Privacy-preserving, anonymous telemetry for adoption analytics.
|
|
5
5
|
* No source code, project names, filesystem paths, or PII collected.
|
|
6
|
+
* Disabled by default; opt in with FELTDB_TELEMETRY=1.
|
|
6
7
|
* Fail-open: telemetry failures never affect FeltDB operation.
|
|
7
8
|
*/
|
|
8
9
|
const isBrowserRuntime = () => typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
@@ -99,9 +100,9 @@ export class TelemetryClient {
|
|
|
99
100
|
constructor(coreVersion = '0.5.7') {
|
|
100
101
|
this.coreVersion = coreVersion;
|
|
101
102
|
this.identity = new InstallationIdentity();
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
// Telemetry is off by default; opt in with FELTDB_TELEMETRY=1 or true
|
|
104
|
+
const optIn = environmentValue('FELTDB_TELEMETRY')?.toLowerCase();
|
|
105
|
+
this.enabled = optIn === '1' || optIn === 'true';
|
|
105
106
|
// Detect browser environment
|
|
106
107
|
if (isBrowserRuntime()) {
|
|
107
108
|
this.runtime = 'browser';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction identity: what a transaction ID is bound to.
|
|
3
|
+
*
|
|
4
|
+
* A transaction ID names one logical transaction *and* its contents. The
|
|
5
|
+
* embedded runtimes record the ID together with a digest of the request, so a
|
|
6
|
+
* retry can be told apart from a different request that happens to reuse the
|
|
7
|
+
* ID. The design and its compatibility analysis are in
|
|
8
|
+
* `adrs/transaction-identity-and-payload-binding.md`.
|
|
9
|
+
*
|
|
10
|
+
* Everything here is synchronous and dependency-free (SHA-256 is the portable
|
|
11
|
+
* implementation in `stable-hash.ts`), because the digest must
|
|
12
|
+
* be computed before a runtime opens its commit boundary (an IndexedDB
|
|
13
|
+
* transaction cannot be held open across an `await`) and must behave the same
|
|
14
|
+
* in Node and in a browser served from an insecure origin, where
|
|
15
|
+
* `crypto.subtle` is unavailable.
|
|
16
|
+
*/
|
|
17
|
+
import type { AtomicTransactionRequest } from './transaction.js';
|
|
18
|
+
/** The construction version this build writes. */
|
|
19
|
+
export declare const TRANSACTION_DIGEST_VERSION = "txd1";
|
|
20
|
+
/** A request that cannot be given an identity because it is not valid. */
|
|
21
|
+
export declare class InvalidTransactionPayload extends Error {
|
|
22
|
+
constructor(message: string);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Serialize `value` as RFC 8785 canonical JSON.
|
|
26
|
+
*
|
|
27
|
+
* Object members are sorted by UTF-16 code unit, numbers use the ECMAScript
|
|
28
|
+
* shortest form (`-0` is `0`), strings use the standard escapes, and there is
|
|
29
|
+
* no insignificant whitespace. Members whose value is `undefined` are omitted,
|
|
30
|
+
* exactly as `JSON.stringify` and a caller who left them out would produce.
|
|
31
|
+
* Array order is preserved.
|
|
32
|
+
*
|
|
33
|
+
* Anything that is not a JSON value is refused rather than coerced: `NaN`,
|
|
34
|
+
* `Infinity`, `undefined` in an array, `BigInt`, symbols, functions, cycles,
|
|
35
|
+
* and non-plain objects such as `Date` or `Map`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function canonicalJsonStrict(value: unknown, where?: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* The semantic request: what the runtime acts on, and nothing else.
|
|
40
|
+
*
|
|
41
|
+
* The transaction ID is the key the digest is stored under, so it is not part
|
|
42
|
+
* of it. Operations, preconditions and fences are ordered arrays; reordering
|
|
43
|
+
* them is a different request.
|
|
44
|
+
*/
|
|
45
|
+
export declare function semanticRequest(request: AtomicTransactionRequest): Record<string, unknown>;
|
|
46
|
+
/**
|
|
47
|
+
* `txd1:sha256:<hex>` over the canonical form of the semantic request.
|
|
48
|
+
*
|
|
49
|
+
* @throws InvalidTransactionPayload when the request holds a non-JSON value
|
|
50
|
+
*/
|
|
51
|
+
export declare function transactionDigest(request: AtomicTransactionRequest): string;
|
|
52
|
+
/** What a stored digest says about a retry's digest. */
|
|
53
|
+
export type DigestComparison = 'match' | 'mismatch' | 'unverifiable';
|
|
54
|
+
/**
|
|
55
|
+
* Compare a recorded digest with a retry's.
|
|
56
|
+
*
|
|
57
|
+
* A digest of a version this build cannot compute, or one that is not a
|
|
58
|
+
* well-formed digest at all, cannot be judged either way, so it is neither a
|
|
59
|
+
* match nor a mismatch: the caller must fail closed.
|
|
60
|
+
*/
|
|
61
|
+
export declare function compareDigests(stored: unknown, computed: string): DigestComparison;
|
|
62
|
+
//# sourceMappingURL=transaction-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-identity.d.ts","sourceRoot":"","sources":["../src/transaction-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,kDAAkD;AAClD,eAAO,MAAM,0BAA0B,SAAS,CAAC;AAKjD,0EAA0E;AAC1E,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAU,GAAG,MAAM,CAE3E;AA+DD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM1F;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAG3E;AAED,wDAAwD;AACxD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAKlF"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { sha256Hex } from './stable-hash.js';
|
|
2
|
+
/** The construction version this build writes. */
|
|
3
|
+
export const TRANSACTION_DIGEST_VERSION = 'txd1';
|
|
4
|
+
/** `txd1:sha256:<64 lowercase hex>` -- the prefix names the whole construction. */
|
|
5
|
+
const DIGEST_FORM = /^(txd\d+):sha256:[0-9a-f]{64}$/;
|
|
6
|
+
/** A request that cannot be given an identity because it is not valid. */
|
|
7
|
+
export class InvalidTransactionPayload extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = 'InvalidTransactionPayload';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/* ---------------------------------------------------------------------------
|
|
14
|
+
* Canonical JSON (RFC 8785)
|
|
15
|
+
* ------------------------------------------------------------------------ */
|
|
16
|
+
const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
17
|
+
function canonicalString(text, where) {
|
|
18
|
+
if (LONE_SURROGATE.test(text))
|
|
19
|
+
throw new InvalidTransactionPayload(`${where} contains a lone surrogate, which has no UTF-8 form`);
|
|
20
|
+
return JSON.stringify(text);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Serialize `value` as RFC 8785 canonical JSON.
|
|
24
|
+
*
|
|
25
|
+
* Object members are sorted by UTF-16 code unit, numbers use the ECMAScript
|
|
26
|
+
* shortest form (`-0` is `0`), strings use the standard escapes, and there is
|
|
27
|
+
* no insignificant whitespace. Members whose value is `undefined` are omitted,
|
|
28
|
+
* exactly as `JSON.stringify` and a caller who left them out would produce.
|
|
29
|
+
* Array order is preserved.
|
|
30
|
+
*
|
|
31
|
+
* Anything that is not a JSON value is refused rather than coerced: `NaN`,
|
|
32
|
+
* `Infinity`, `undefined` in an array, `BigInt`, symbols, functions, cycles,
|
|
33
|
+
* and non-plain objects such as `Date` or `Map`.
|
|
34
|
+
*/
|
|
35
|
+
export function canonicalJsonStrict(value, where = 'value') {
|
|
36
|
+
return write(value, where, new Set());
|
|
37
|
+
}
|
|
38
|
+
function write(value, where, active) {
|
|
39
|
+
if (value === null)
|
|
40
|
+
return 'null';
|
|
41
|
+
switch (typeof value) {
|
|
42
|
+
case 'boolean': return value ? 'true' : 'false';
|
|
43
|
+
case 'string': return canonicalString(value, where);
|
|
44
|
+
case 'number':
|
|
45
|
+
if (!Number.isFinite(value))
|
|
46
|
+
throw new InvalidTransactionPayload(`${where} is ${value}, which is not a JSON number`);
|
|
47
|
+
return String(value);
|
|
48
|
+
case 'object': break;
|
|
49
|
+
default:
|
|
50
|
+
throw new InvalidTransactionPayload(`${where} is a ${typeof value}, which is not a JSON value`);
|
|
51
|
+
}
|
|
52
|
+
const object = value;
|
|
53
|
+
if (active.has(object))
|
|
54
|
+
throw new InvalidTransactionPayload(`${where} is part of a cycle`);
|
|
55
|
+
active.add(object);
|
|
56
|
+
try {
|
|
57
|
+
if (Array.isArray(object)) {
|
|
58
|
+
const parts = [];
|
|
59
|
+
for (let index = 0; index < object.length; index += 1) {
|
|
60
|
+
if (!(index in object) || object[index] === undefined) {
|
|
61
|
+
throw new InvalidTransactionPayload(`${where}[${index}] is ${index in object ? 'undefined' : 'a hole'}; arrays hold JSON values only`);
|
|
62
|
+
}
|
|
63
|
+
parts.push(write(object[index], `${where}[${index}]`, active));
|
|
64
|
+
}
|
|
65
|
+
return `[${parts.join(',')}]`;
|
|
66
|
+
}
|
|
67
|
+
const prototype = Object.getPrototypeOf(object);
|
|
68
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
69
|
+
throw new InvalidTransactionPayload(`${where} is a ${prototype?.constructor?.name ?? 'non-plain object'}; only plain objects are JSON values`);
|
|
70
|
+
}
|
|
71
|
+
const record = object;
|
|
72
|
+
const members = Object.keys(record).filter(key => record[key] !== undefined).sort();
|
|
73
|
+
return `{${members.map(key => `${canonicalString(key, `${where} key`)}:${write(record[key], `${where}.${key}`, active)}`).join(',')}}`;
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
active.delete(object);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/* ---------------------------------------------------------------------------
|
|
80
|
+
* The txd1 digest
|
|
81
|
+
* ------------------------------------------------------------------------ */
|
|
82
|
+
function pick(source, fields, where) {
|
|
83
|
+
const record = source;
|
|
84
|
+
const picked = {};
|
|
85
|
+
for (const field of fields)
|
|
86
|
+
if (record[field] !== undefined)
|
|
87
|
+
picked[field] = record[field];
|
|
88
|
+
// `ifVersion` and `expectedVersion` are one predicate (see
|
|
89
|
+
// `normalisePrecondition`); the digest knows only the wire spelling.
|
|
90
|
+
if (picked.ifVersion !== undefined) {
|
|
91
|
+
if (picked.expectedVersion !== undefined && picked.expectedVersion !== picked.ifVersion) {
|
|
92
|
+
throw new InvalidTransactionPayload(`${where} supplies ifVersion ${String(picked.ifVersion)} and expectedVersion ${String(picked.expectedVersion)}; they are the same predicate`);
|
|
93
|
+
}
|
|
94
|
+
picked.expectedVersion = picked.ifVersion;
|
|
95
|
+
delete picked.ifVersion;
|
|
96
|
+
}
|
|
97
|
+
return picked;
|
|
98
|
+
}
|
|
99
|
+
const OPERATION_FIELDS = ['collection', 'id', 'value', 'requireAbsent', 'ifVersion', 'expectedVersion', 'expectedEpoch', 'expectedLeaseId'];
|
|
100
|
+
const PRECONDITION_FIELDS = ['collection', 'id', 'requireAbsent', 'ifVersion', 'expectedVersion', 'expectedEpoch', 'expectedLeaseId'];
|
|
101
|
+
/**
|
|
102
|
+
* The semantic request: what the runtime acts on, and nothing else.
|
|
103
|
+
*
|
|
104
|
+
* The transaction ID is the key the digest is stored under, so it is not part
|
|
105
|
+
* of it. Operations, preconditions and fences are ordered arrays; reordering
|
|
106
|
+
* them is a different request.
|
|
107
|
+
*/
|
|
108
|
+
export function semanticRequest(request) {
|
|
109
|
+
return {
|
|
110
|
+
operations: request.operations.map((operation, index) => pick(operation, OPERATION_FIELDS, `operations[${index}]`)),
|
|
111
|
+
preconditions: (request.preconditions ?? []).map((condition, index) => pick(condition, PRECONDITION_FIELDS, `preconditions[${index}]`)),
|
|
112
|
+
fences: (request.fences ?? []).map(fence => ({ token: fence.token, reads: fence.reads })),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* `txd1:sha256:<hex>` over the canonical form of the semantic request.
|
|
117
|
+
*
|
|
118
|
+
* @throws InvalidTransactionPayload when the request holds a non-JSON value
|
|
119
|
+
*/
|
|
120
|
+
export function transactionDigest(request) {
|
|
121
|
+
const canonical = canonicalJsonStrict(semanticRequest(request), 'transaction');
|
|
122
|
+
return `${TRANSACTION_DIGEST_VERSION}:sha256:${sha256Hex(canonical)}`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Compare a recorded digest with a retry's.
|
|
126
|
+
*
|
|
127
|
+
* A digest of a version this build cannot compute, or one that is not a
|
|
128
|
+
* well-formed digest at all, cannot be judged either way, so it is neither a
|
|
129
|
+
* match nor a mismatch: the caller must fail closed.
|
|
130
|
+
*/
|
|
131
|
+
export function compareDigests(stored, computed) {
|
|
132
|
+
if (typeof stored !== 'string')
|
|
133
|
+
return 'unverifiable';
|
|
134
|
+
const form = DIGEST_FORM.exec(stored);
|
|
135
|
+
if (!form || form[1] !== TRANSACTION_DIGEST_VERSION)
|
|
136
|
+
return 'unverifiable';
|
|
137
|
+
return stored === computed ? 'match' : 'mismatch';
|
|
138
|
+
}
|
package/dist/transaction.d.ts
CHANGED
|
@@ -166,14 +166,37 @@ export interface AtomicTransactionResult {
|
|
|
166
166
|
transactionId: string;
|
|
167
167
|
/** True when this id was already committed; nothing was applied again. */
|
|
168
168
|
duplicate: boolean;
|
|
169
|
+
/**
|
|
170
|
+
* How a duplicate was recognized (present only when `duplicate` is true on an
|
|
171
|
+
* embedded runtime):
|
|
172
|
+
* - `verified`: the id and the digest of this request both match what was
|
|
173
|
+
* committed, so this request *is* the original one;
|
|
174
|
+
* - `legacy-unverified`: the id was committed by a build that did not record
|
|
175
|
+
* a digest, so only the id could be checked. Treat the outcome as
|
|
176
|
+
* uncertain if the request might differ from the original.
|
|
177
|
+
*/
|
|
178
|
+
binding?: 'verified' | 'legacy-unverified';
|
|
179
|
+
/**
|
|
180
|
+
* Whether the fields below describe the original commit. `unavailable` means
|
|
181
|
+
* the durable record no longer holds the original positions (an id committed
|
|
182
|
+
* by a build that did not record them, since folded into a snapshot); they
|
|
183
|
+
* are then absent rather than guessed. Absent on a first commit, where they
|
|
184
|
+
* are always known.
|
|
185
|
+
*/
|
|
186
|
+
outcome?: 'original' | 'unavailable';
|
|
169
187
|
operations: number;
|
|
170
|
-
|
|
171
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Position of the *original* commit: the store's sequence before and after
|
|
190
|
+
* it, not the store's current sequence. Absent when `outcome` is
|
|
191
|
+
* `unavailable`.
|
|
192
|
+
*/
|
|
193
|
+
stateBefore?: number;
|
|
194
|
+
stateAfter?: number;
|
|
172
195
|
/** Authority revision before and after this atomic commit. */
|
|
173
|
-
baseRevision
|
|
174
|
-
commitRevision
|
|
196
|
+
baseRevision?: number;
|
|
197
|
+
commitRevision?: number;
|
|
175
198
|
/** Stable revision and operation identities; never aliases of transactionId. */
|
|
176
|
-
revisionId
|
|
199
|
+
revisionId?: string;
|
|
177
200
|
operationIds: string[];
|
|
178
201
|
}
|
|
179
202
|
/** Staging surface for one collection inside a transaction. */
|
|
@@ -234,6 +257,28 @@ export declare class AtomicTransactionError extends Error {
|
|
|
234
257
|
readonly status?: number;
|
|
235
258
|
constructor(message: string, transactionId: string, code?: string, status?: number, cause?: unknown);
|
|
236
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* The transaction id was already committed with a different payload.
|
|
262
|
+
*
|
|
263
|
+
* Nothing was applied and the recorded transaction is unchanged. Retrying with
|
|
264
|
+
* the same id cannot succeed: choose a new id for a new transaction, or resend
|
|
265
|
+
* the original payload to confirm the original.
|
|
266
|
+
*/
|
|
267
|
+
export declare class TransactionIdConflictError extends AtomicTransactionError {
|
|
268
|
+
readonly code: "IDEMPOTENCY_CONFLICT";
|
|
269
|
+
constructor(transactionId: string, message?: string);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The transaction id exists, but its recorded identity cannot be checked by
|
|
273
|
+
* this build (a digest of a newer construction, or a malformed one).
|
|
274
|
+
*
|
|
275
|
+
* Not a conflict and not a duplicate: neither can be established. Nothing was
|
|
276
|
+
* applied. Do not assume either outcome.
|
|
277
|
+
*/
|
|
278
|
+
export declare class TransactionIdUnverifiableError extends AtomicTransactionError {
|
|
279
|
+
readonly code: "IDEMPOTENCY_UNVERIFIABLE";
|
|
280
|
+
constructor(transactionId: string, message?: string);
|
|
281
|
+
}
|
|
237
282
|
/** Which predicate failed, and what the authority actually holds. */
|
|
238
283
|
export interface ConditionalConflictDetail {
|
|
239
284
|
predicate: 'version' | 'epoch' | 'lease' | 'present' | 'missing' | 'fence';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,iCAAiC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,yDAAyD;AACzD,MAAM,WAAW,sBAAsB;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,0DAA0D;AAC1D,MAAM,WAAW,iCAAiC;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,iFAAiF;IACjF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,yBAAyB;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAChD,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAChC,UAAU,EAAE,iCAAiC,EAAE,CAAC;CACjD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,OAAO,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC1F;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yEAAyE;AACzE,eAAO,MAAM,0BAA0B,OAAQ,CAAC;AAIhD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAgCxF;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,iCAAiC,EAAE,CAAC;IAChD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAChD;;;;OAIG;IACH,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"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"}
|
package/dist/transaction.js
CHANGED
|
@@ -79,6 +79,34 @@ export class AtomicTransactionError extends Error {
|
|
|
79
79
|
this.status = status;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* The transaction id was already committed with a different payload.
|
|
84
|
+
*
|
|
85
|
+
* Nothing was applied and the recorded transaction is unchanged. Retrying with
|
|
86
|
+
* the same id cannot succeed: choose a new id for a new transaction, or resend
|
|
87
|
+
* the original payload to confirm the original.
|
|
88
|
+
*/
|
|
89
|
+
export class TransactionIdConflictError extends AtomicTransactionError {
|
|
90
|
+
code = 'IDEMPOTENCY_CONFLICT';
|
|
91
|
+
constructor(transactionId, message) {
|
|
92
|
+
super(message ?? `Transaction ${transactionId} was already committed with a different payload`, transactionId);
|
|
93
|
+
this.name = 'TransactionIdConflictError';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The transaction id exists, but its recorded identity cannot be checked by
|
|
98
|
+
* this build (a digest of a newer construction, or a malformed one).
|
|
99
|
+
*
|
|
100
|
+
* Not a conflict and not a duplicate: neither can be established. Nothing was
|
|
101
|
+
* applied. Do not assume either outcome.
|
|
102
|
+
*/
|
|
103
|
+
export class TransactionIdUnverifiableError extends AtomicTransactionError {
|
|
104
|
+
code = 'IDEMPOTENCY_UNVERIFIABLE';
|
|
105
|
+
constructor(transactionId, message) {
|
|
106
|
+
super(message ?? `Transaction ${transactionId} exists, but its recorded identity cannot be verified by this build`, transactionId);
|
|
107
|
+
this.name = 'TransactionIdUnverifiableError';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
82
110
|
/**
|
|
83
111
|
* A transaction was refused because a precondition did not hold.
|
|
84
112
|
*
|
|
Binary file
|
package/dist/wasm/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feltdb/core",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "FeltDB Core - Application-facing database with Browser, Local, and Server runtimes. Durable state, reactive APIs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"README.md"
|
|
62
62
|
],
|
|
63
63
|
"scripts": {
|
|
64
|
-
"build": "rm -rf dist && tsc && node ../../tools/stage-core-wasm.mjs && npm run build --workspace @feltdb/react && npm run build --workspace @feltdb/migration-sherpa && npm run build --workspace @feltdb/studio && npm run build --workspace create-feltdb && npm run build --workspace @feltdb/cli && node ../../tools/assemble-core-sdk.mjs",
|
|
64
|
+
"build": "rm -rf dist && tsc && node ../../tools/stage-core-wasm.mjs && npm run build --workspace @feltdb/react && npm run build --workspace @feltdb/migration-sherpa && npm run build --workspace @feltdb/studio && npm run build --workspace create-feltdb && npm run build --workspace @feltdb/cli && node ../../tools/assemble-core-sdk.mjs && node ../../tools/core-build-identity.mjs write packages/core",
|
|
65
65
|
"test": "node ../../test-runner.ts",
|
|
66
66
|
"test:workspace-e2e": "node --test test/workspace-connection.e2e.test.mjs test/local-development-authority-read-contract.test.mjs",
|
|
67
67
|
"type-check": "tsc --noEmit"
|
|
File without changes
|