@lssm/lib.contracts-runtime-core 3.0.1
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 +110 -0
- package/dist/approval.d.ts +13 -0
- package/dist/approval.js +2 -0
- package/dist/approval.test.d.ts +1 -0
- package/dist/browser/approval.js +1 -0
- package/dist/browser/collaboration.js +0 -0
- package/dist/browser/contracts-runtime-core.feature.js +1 -0
- package/dist/browser/engine/backoff.js +1 -0
- package/dist/browser/engine/cache-store.js +1 -0
- package/dist/browser/engine/conflict-registry.js +1 -0
- package/dist/browser/engine/conflict-resolution.js +1 -0
- package/dist/browser/engine/data-engine-host.js +1 -0
- package/dist/browser/engine/data-engine-test-helpers.js +1 -0
- package/dist/browser/engine/data-engine.js +1 -0
- package/dist/browser/engine/dedup.js +1 -0
- package/dist/browser/engine/events.js +1 -0
- package/dist/browser/engine/index.js +1 -0
- package/dist/browser/engine/maintenance.js +1 -0
- package/dist/browser/engine/mutation-engine.js +1 -0
- package/dist/browser/engine/mutation-queue.js +1 -0
- package/dist/browser/engine/mutation-types.js +0 -0
- package/dist/browser/engine/no-cache-store.js +1 -0
- package/dist/browser/engine/online-only-data-engine.js +1 -0
- package/dist/browser/engine/online-only-mutation-engine.js +1 -0
- package/dist/browser/engine/query-engine.js +1 -0
- package/dist/browser/engine/state.js +1 -0
- package/dist/browser/engine/types.js +0 -0
- package/dist/browser/forms-platform-csv-columns.js +1 -0
- package/dist/browser/forms-platform-csv.js +2 -0
- package/dist/browser/forms-platform-management.js +1 -0
- package/dist/browser/forms-platform-navigation.js +1 -0
- package/dist/browser/forms-platform-submission.js +1 -0
- package/dist/browser/forms-platform-types.js +1 -0
- package/dist/browser/forms-platform-utils.js +1 -0
- package/dist/browser/forms-platform.js +2 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/local-offline.js +1 -0
- package/dist/browser/observability.js +1 -0
- package/dist/browser/reachability.js +1 -0
- package/dist/browser/redaction.js +1 -0
- package/dist/browser/storage/indexeddb.web.js +1 -0
- package/dist/browser/storage/keyed-store.js +1 -0
- package/dist/browser/storage/memory.js +1 -0
- package/dist/browser/storage/port.js +1 -0
- package/dist/browser/transport.js +2 -0
- package/dist/collaboration.d.ts +57 -0
- package/dist/collaboration.js +1 -0
- package/dist/contracts-runtime-core.feature.d.ts +1 -0
- package/dist/contracts-runtime-core.feature.js +2 -0
- package/dist/engine/backoff.d.ts +16 -0
- package/dist/engine/backoff.js +2 -0
- package/dist/engine/backoff.test.d.ts +1 -0
- package/dist/engine/cache-store.d.ts +19 -0
- package/dist/engine/cache-store.js +2 -0
- package/dist/engine/conflict-registry.d.ts +10 -0
- package/dist/engine/conflict-registry.js +2 -0
- package/dist/engine/conflict-registry.test.d.ts +1 -0
- package/dist/engine/conflict-resolution.d.ts +24 -0
- package/dist/engine/conflict-resolution.js +2 -0
- package/dist/engine/conflict-resolution.test.d.ts +1 -0
- package/dist/engine/data-engine-host.d.ts +30 -0
- package/dist/engine/data-engine-host.js +2 -0
- package/dist/engine/data-engine-local-offline.test.d.ts +1 -0
- package/dist/engine/data-engine-test-helpers.d.ts +30 -0
- package/dist/engine/data-engine-test-helpers.js +2 -0
- package/dist/engine/data-engine.d.ts +46 -0
- package/dist/engine/data-engine.js +2 -0
- package/dist/engine/data-engine.test.d.ts +1 -0
- package/dist/engine/dedup.d.ts +9 -0
- package/dist/engine/dedup.js +2 -0
- package/dist/engine/events.d.ts +76 -0
- package/dist/engine/events.economic-evidence.test.d.ts +1 -0
- package/dist/engine/events.js +2 -0
- package/dist/engine/index.d.ts +17 -0
- package/dist/engine/index.js +2 -0
- package/dist/engine/maintenance.d.ts +18 -0
- package/dist/engine/maintenance.js +2 -0
- package/dist/engine/maintenance.test.d.ts +1 -0
- package/dist/engine/mutation-engine.d.ts +2 -0
- package/dist/engine/mutation-engine.js +2 -0
- package/dist/engine/mutation-queue.d.ts +16 -0
- package/dist/engine/mutation-queue.js +2 -0
- package/dist/engine/mutation-queue.test.d.ts +1 -0
- package/dist/engine/mutation-types.d.ts +118 -0
- package/dist/engine/mutation-types.js +1 -0
- package/dist/engine/no-cache-store.d.ts +3 -0
- package/dist/engine/no-cache-store.js +2 -0
- package/dist/engine/online-only-data-engine.d.ts +9 -0
- package/dist/engine/online-only-data-engine.js +2 -0
- package/dist/engine/online-only-mutation-engine.d.ts +3 -0
- package/dist/engine/online-only-mutation-engine.js +2 -0
- package/dist/engine/query-engine.d.ts +7 -0
- package/dist/engine/query-engine.js +2 -0
- package/dist/engine/query-engine.test.d.ts +1 -0
- package/dist/engine/state.d.ts +37 -0
- package/dist/engine/state.js +2 -0
- package/dist/engine/types.d.ts +70 -0
- package/dist/engine/types.js +1 -0
- package/dist/forms-platform-choice.test.d.ts +1 -0
- package/dist/forms-platform-csv-columns.d.ts +7 -0
- package/dist/forms-platform-csv-columns.js +2 -0
- package/dist/forms-platform-csv.d.ts +12 -0
- package/dist/forms-platform-csv.js +3 -0
- package/dist/forms-platform-management.d.ts +12 -0
- package/dist/forms-platform-management.js +2 -0
- package/dist/forms-platform-navigation.d.ts +2 -0
- package/dist/forms-platform-navigation.js +2 -0
- package/dist/forms-platform-submission.d.ts +7 -0
- package/dist/forms-platform-submission.js +2 -0
- package/dist/forms-platform-types.d.ts +51 -0
- package/dist/forms-platform-types.js +2 -0
- package/dist/forms-platform-utils.d.ts +6 -0
- package/dist/forms-platform-utils.js +2 -0
- package/dist/forms-platform-utils.test.d.ts +1 -0
- package/dist/forms-platform.d.ts +19 -0
- package/dist/forms-platform.js +3 -0
- package/dist/forms-platform.test.d.ts +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +4 -0
- package/dist/local-offline.d.ts +17 -0
- package/dist/local-offline.js +2 -0
- package/dist/local-offline.test.d.ts +1 -0
- package/dist/native/approval.js +130 -0
- package/dist/native/collaboration.js +0 -0
- package/dist/native/contracts-runtime-core.feature.js +17 -0
- package/dist/native/engine/backoff.js +16 -0
- package/dist/native/engine/cache-store.js +49 -0
- package/dist/native/engine/conflict-registry.js +51 -0
- package/dist/native/engine/conflict-resolution.js +81 -0
- package/dist/native/engine/data-engine-host.js +1119 -0
- package/dist/native/engine/data-engine-test-helpers.js +117 -0
- package/dist/native/engine/data-engine.js +1106 -0
- package/dist/native/engine/dedup.js +22 -0
- package/dist/native/engine/events.js +19 -0
- package/dist/native/engine/index.js +1189 -0
- package/dist/native/engine/maintenance.js +36 -0
- package/dist/native/engine/mutation-engine.js +360 -0
- package/dist/native/engine/mutation-queue.js +26 -0
- package/dist/native/engine/mutation-types.js +0 -0
- package/dist/native/engine/no-cache-store.js +15 -0
- package/dist/native/engine/online-only-data-engine.js +422 -0
- package/dist/native/engine/online-only-mutation-engine.js +70 -0
- package/dist/native/engine/query-engine.js +360 -0
- package/dist/native/engine/state.js +116 -0
- package/dist/native/engine/types.js +0 -0
- package/dist/native/forms-platform-csv-columns.js +31 -0
- package/dist/native/forms-platform-csv.js +150 -0
- package/dist/native/forms-platform-management.js +179 -0
- package/dist/native/forms-platform-navigation.js +27 -0
- package/dist/native/forms-platform-submission.js +207 -0
- package/dist/native/forms-platform-types.js +12 -0
- package/dist/native/forms-platform-utils.js +69 -0
- package/dist/native/forms-platform.js +429 -0
- package/dist/native/index.js +1879 -0
- package/dist/native/local-offline.js +81 -0
- package/dist/native/observability.js +182 -0
- package/dist/native/reachability.js +28 -0
- package/dist/native/redaction.js +44 -0
- package/dist/native/storage/async-storage.native.js +91 -0
- package/dist/native/storage/keyed-store.js +74 -0
- package/dist/native/storage/memory.js +26 -0
- package/dist/native/storage/port.js +16 -0
- package/dist/native/transport.js +27 -0
- package/dist/node/approval.js +1 -0
- package/dist/node/collaboration.js +0 -0
- package/dist/node/contracts-runtime-core.feature.js +1 -0
- package/dist/node/engine/backoff.js +1 -0
- package/dist/node/engine/cache-store.js +1 -0
- package/dist/node/engine/conflict-registry.js +1 -0
- package/dist/node/engine/conflict-resolution.js +1 -0
- package/dist/node/engine/data-engine-host.js +1 -0
- package/dist/node/engine/data-engine-test-helpers.js +1 -0
- package/dist/node/engine/data-engine.js +1 -0
- package/dist/node/engine/dedup.js +1 -0
- package/dist/node/engine/events.js +1 -0
- package/dist/node/engine/index.js +1 -0
- package/dist/node/engine/maintenance.js +1 -0
- package/dist/node/engine/mutation-engine.js +1 -0
- package/dist/node/engine/mutation-queue.js +1 -0
- package/dist/node/engine/mutation-types.js +0 -0
- package/dist/node/engine/no-cache-store.js +1 -0
- package/dist/node/engine/online-only-data-engine.js +1 -0
- package/dist/node/engine/online-only-mutation-engine.js +1 -0
- package/dist/node/engine/query-engine.js +1 -0
- package/dist/node/engine/state.js +1 -0
- package/dist/node/engine/types.js +0 -0
- package/dist/node/forms-platform-csv-columns.js +1 -0
- package/dist/node/forms-platform-csv.js +2 -0
- package/dist/node/forms-platform-management.js +1 -0
- package/dist/node/forms-platform-navigation.js +1 -0
- package/dist/node/forms-platform-submission.js +1 -0
- package/dist/node/forms-platform-types.js +1 -0
- package/dist/node/forms-platform-utils.js +1 -0
- package/dist/node/forms-platform.js +2 -0
- package/dist/node/index.js +3 -0
- package/dist/node/local-offline.js +1 -0
- package/dist/node/observability.js +1 -0
- package/dist/node/reachability.js +1 -0
- package/dist/node/redaction.js +1 -0
- package/dist/node/storage/keyed-store.js +1 -0
- package/dist/node/storage/memory.js +1 -0
- package/dist/node/storage/port.js +1 -0
- package/dist/node/transport.js +2 -0
- package/dist/observability.d.ts +34 -0
- package/dist/observability.js +2 -0
- package/dist/observability.test.d.ts +1 -0
- package/dist/reachability.d.ts +63 -0
- package/dist/reachability.js +2 -0
- package/dist/reachability.test.d.ts +1 -0
- package/dist/redaction.d.ts +34 -0
- package/dist/redaction.js +2 -0
- package/dist/redaction.test.d.ts +1 -0
- package/dist/storage/async-storage.native.d.ts +23 -0
- package/dist/storage/async-storage.native.test.d.ts +1 -0
- package/dist/storage/indexeddb.web.d.ts +13 -0
- package/dist/storage/indexeddb.web.js +2 -0
- package/dist/storage/keyed-store.d.ts +25 -0
- package/dist/storage/keyed-store.js +2 -0
- package/dist/storage/keyed-store.test.d.ts +1 -0
- package/dist/storage/memory.d.ts +11 -0
- package/dist/storage/memory.js +2 -0
- package/dist/storage/memory.test.d.ts +1 -0
- package/dist/storage/port.d.ts +34 -0
- package/dist/storage/port.js +2 -0
- package/dist/transport.d.ts +53 -0
- package/dist/transport.js +3 -0
- package/package.json +219 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Transforms a value before it is persisted (e.g. stripping secrets). */
|
|
2
|
+
export type RedactionPolicy = (value: unknown) => unknown;
|
|
3
|
+
/**
|
|
4
|
+
* Recursively replace the values of secret-ish keys with a redaction marker so
|
|
5
|
+
* durable cache/queue state never persists secrets (AC12). Non-secret data is
|
|
6
|
+
* preserved structurally.
|
|
7
|
+
*/
|
|
8
|
+
export declare function redactSecrets(value: unknown): unknown;
|
|
9
|
+
/**
|
|
10
|
+
* Encryption-at-rest seam. The default is identity (no encryption); sensitive
|
|
11
|
+
* entities plug a real cipher here without the storage core knowing the scheme.
|
|
12
|
+
*/
|
|
13
|
+
export interface EncryptionSeam {
|
|
14
|
+
encrypt(plaintext: string): string | Promise<string>;
|
|
15
|
+
decrypt(ciphertext: string): string | Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
export declare const identityEncryption: EncryptionSeam;
|
|
18
|
+
/**
|
|
19
|
+
* Stable non-cryptographic hash (FNV-1a) used to log query keys without leaking
|
|
20
|
+
* the input they embed. Observability must never log raw keys (PII).
|
|
21
|
+
*/
|
|
22
|
+
export declare function hashKey(key: string): string;
|
|
23
|
+
export declare const redactionDoc: {
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
summary: string;
|
|
27
|
+
kind: "reference";
|
|
28
|
+
visibility: "internal";
|
|
29
|
+
route: string;
|
|
30
|
+
domain: string;
|
|
31
|
+
owners: string[];
|
|
32
|
+
tags: string[];
|
|
33
|
+
body: string;
|
|
34
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var s=/(?:token|secret|password|passwd|authorization|api[_-]?key|credential|cookie|session)/i;function n(t){if(Array.isArray(t))return t.map(n);if(t===null||typeof t!=="object")return t;let e={};for(let[r,o]of Object.entries(t))e[r]=s.test(r)?"[REDACTED]":n(o);return e}var i={encrypt:(t)=>t,decrypt:(t)=>t};function c(t){let e=2166136261;for(let r=0;r<t.length;r+=1)e^=t.charCodeAt(r),e=Math.imul(e,16777619);return(e>>>0).toString(16).padStart(8,"0")}var a={id:"docs.contracts-runtime-core.redaction",title:"Persisted-state redaction + encryption-at-rest seam",summary:"Secret redaction for durable state plus an encryption-at-rest seam and a PII-safe key hash for logs.",kind:"reference",visibility:"internal",route:"/docs/contracts-runtime-core/redaction",domain:"contracts-runtime-core",owners:["@contractspec-core"],tags:["contracts-runtime-core","security","redaction","encryption"],body:"redactSecrets recursively strips secret-ish keys (token/secret/password/authorization/api-key/credential/cookie/session) so durable cache+queue state never persists secrets (AC12). EncryptionSeam is the encryption-at-rest seam \u2014 default identityEncryption (no-op); sensitive entities plug a real cipher transparently to the storage core. hashKey (FNV-1a) lets observability correlate on a stable key id without logging the raw query key (which embeds input/PII)."};export{c as hashKey,i as identityEncryption,n as redactSecrets,a as redactionDoc};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type KeyedStorageOptions } from './keyed-store.js';
|
|
2
|
+
import type { StoragePort } from './port.js';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal AsyncStorage surface. Typed locally so this lib takes no hard
|
|
5
|
+
* dependency on `@react-native-async-storage/async-storage`; the app injects
|
|
6
|
+
* its own instance (which satisfies this shape).
|
|
7
|
+
*/
|
|
8
|
+
export interface AsyncStorageLike {
|
|
9
|
+
getItem(key: string): Promise<string | null>;
|
|
10
|
+
setItem(key: string, value: string): Promise<void>;
|
|
11
|
+
removeItem(key: string): Promise<void>;
|
|
12
|
+
getAllKeys(): Promise<readonly string[]>;
|
|
13
|
+
clear(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Durable native {@link StoragePort} backed by an injected AsyncStorage
|
|
17
|
+
* instance. React Native apps pass their AsyncStorage; the lib stays
|
|
18
|
+
* dependency-free and platform-agnostic at the type level.
|
|
19
|
+
*
|
|
20
|
+
* Secret redaction is ON by default (AC12: durable state never persists
|
|
21
|
+
* secrets). Callers opt out with `redact: undefined` or supply a custom policy.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createAsyncStorage(store: AsyncStorageLike, options?: KeyedStorageOptions): StoragePort;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type KeyedStorageOptions } from './keyed-store.js';
|
|
2
|
+
import type { StoragePort } from './port.js';
|
|
3
|
+
export interface IndexedDbStorageOptions extends KeyedStorageOptions {
|
|
4
|
+
databaseName?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Durable web {@link StoragePort} backed by IndexedDB. Browser-only — apps
|
|
8
|
+
* import this from the web lane; native lanes use `createAsyncStorage`.
|
|
9
|
+
*
|
|
10
|
+
* Secret redaction is ON by default (AC12: durable state never persists
|
|
11
|
+
* secrets). Callers opt out with `redact: undefined` or supply a custom policy.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createIndexedDbStorage(options?: IndexedDbStorageOptions): StoragePort;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var f=/(?:token|secret|password|passwd|authorization|api[_-]?key|credential|cookie|session)/i;function d(e){if(Array.isArray(e))return e.map(d);if(e===null||typeof e!=="object")return e;let n={};for(let[t,r]of Object.entries(e))n[t]=f.test(t)?"[REDACTED]":d(r);return n}var u={encrypt:(e)=>e,decrypt:(e)=>e};function h(e){let n=2166136261;for(let t=0;t<e.length;t+=1)n^=e.charCodeAt(t),n=Math.imul(n,16777619);return(n>>>0).toString(16).padStart(8,"0")}var D={id:"docs.contracts-runtime-core.redaction",title:"Persisted-state redaction + encryption-at-rest seam",summary:"Secret redaction for durable state plus an encryption-at-rest seam and a PII-safe key hash for logs.",kind:"reference",visibility:"internal",route:"/docs/contracts-runtime-core/redaction",domain:"contracts-runtime-core",owners:["@contractspec-core"],tags:["contracts-runtime-core","security","redaction","encryption"],body:"redactSecrets recursively strips secret-ish keys (token/secret/password/authorization/api-key/credential/cookie/session) so durable cache+queue state never persists secrets (AC12). EncryptionSeam is the encryption-at-rest seam \u2014 default identityEncryption (no-op); sensitive entities plug a real cipher transparently to the storage core. hashKey (FNV-1a) lets observability correlate on a stable key id without logging the raw query key (which embeds input/PII)."};function g(e,n={}){let t=n.encryption??u,r=n.redact,i=n.namespace??"",y=(o)=>`${i}${o}`,l=(o)=>i!==""&&o.startsWith(i)?o.slice(i.length):o;return{async get(o){let s=await e.getItem(y(o));if(s===null)return;let a=await t.decrypt(s);return JSON.parse(a)},async set(o,s){let a=JSON.stringify(r===void 0?s:r(s));await e.setItem(y(o),await t.encrypt(a))},async remove(o){await e.removeItem(y(o))},async keys(o){let s=await e.keys(),a=i===""?s:s.filter((p)=>p.startsWith(i)).map(l);return o===void 0?a:a.filter((p)=>p.startsWith(o))},async clear(){await e.clear()}}}var w="contractspec-runtime",m="kv";function c(e){return new Promise((n,t)=>{e.onsuccess=()=>n(e.result),e.onerror=()=>t(e.error)})}function S(e){return new Promise((n,t)=>{let r=indexedDB.open(e,1);r.onupgradeneeded=()=>{r.result.createObjectStore(m)},r.onsuccess=()=>n(r.result),r.onerror=()=>t(r.error)})}function k(e){let n=S(e),t=async(r)=>(await n).transaction(m,r).objectStore(m);return{async getItem(r){return await c((await t("readonly")).get(r))??null},async setItem(r,i){await c((await t("readwrite")).put(i,r))},async removeItem(r){await c((await t("readwrite")).delete(r))},async keys(){return(await c((await t("readonly")).getAllKeys())).map(String)},async clear(){await c((await t("readwrite")).clear())}}}function I(e={}){let{databaseName:n,...t}=e;return g(k(n??w),{redact:d,...t})}export{I as createIndexedDbStorage};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type EncryptionSeam, type RedactionPolicy } from '../redaction.js';
|
|
2
|
+
import type { StoragePort } from './port.js';
|
|
3
|
+
/** Minimal async string key/value driver a platform binding adapts to. */
|
|
4
|
+
export interface StringKvDriver {
|
|
5
|
+
getItem(key: string): Promise<string | null>;
|
|
6
|
+
setItem(key: string, value: string): Promise<void>;
|
|
7
|
+
removeItem(key: string): Promise<void>;
|
|
8
|
+
keys(): Promise<readonly string[]>;
|
|
9
|
+
clear(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export interface KeyedStorageOptions {
|
|
12
|
+
/** Redaction applied to values before persistence (default: none). */
|
|
13
|
+
redact?: RedactionPolicy;
|
|
14
|
+
/** Encryption-at-rest seam wrapping the serialized JSON (default: identity). */
|
|
15
|
+
encryption?: EncryptionSeam;
|
|
16
|
+
/** Key namespace prefix applied to every driver key (default: none). */
|
|
17
|
+
namespace?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds a durable {@link StoragePort} over a string KV driver, adding JSON
|
|
21
|
+
* (de)serialization, optional secret redaction, the encryption-at-rest seam,
|
|
22
|
+
* and key namespacing. This is the shared, fully testable core behind the
|
|
23
|
+
* platform bindings (IndexedDB on web, AsyncStorage on native).
|
|
24
|
+
*/
|
|
25
|
+
export declare function createKeyedStorage(driver: StringKvDriver, options?: KeyedStorageOptions): StoragePort;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var u=/(?:token|secret|password|passwd|authorization|api[_-]?key|credential|cookie|session)/i;function p(t){if(Array.isArray(t))return t.map(p);if(t===null||typeof t!=="object")return t;let r={};for(let[n,c]of Object.entries(t))r[n]=u.test(n)?"[REDACTED]":p(c);return r}var d={encrypt:(t)=>t,decrypt:(t)=>t};function g(t){let r=2166136261;for(let n=0;n<t.length;n+=1)r^=t.charCodeAt(n),r=Math.imul(r,16777619);return(r>>>0).toString(16).padStart(8,"0")}var l={id:"docs.contracts-runtime-core.redaction",title:"Persisted-state redaction + encryption-at-rest seam",summary:"Secret redaction for durable state plus an encryption-at-rest seam and a PII-safe key hash for logs.",kind:"reference",visibility:"internal",route:"/docs/contracts-runtime-core/redaction",domain:"contracts-runtime-core",owners:["@contractspec-core"],tags:["contracts-runtime-core","security","redaction","encryption"],body:"redactSecrets recursively strips secret-ish keys (token/secret/password/authorization/api-key/credential/cookie/session) so durable cache+queue state never persists secrets (AC12). EncryptionSeam is the encryption-at-rest seam \u2014 default identityEncryption (no-op); sensitive entities plug a real cipher transparently to the storage core. hashKey (FNV-1a) lets observability correlate on a stable key id without logging the raw query key (which embeds input/PII)."};function k(t,r={}){let n=r.encryption??d,c=r.redact,o=r.namespace??"",a=(e)=>`${o}${e}`,m=(e)=>o!==""&&e.startsWith(o)?e.slice(o.length):e;return{async get(e){let i=await t.getItem(a(e));if(i===null)return;let s=await n.decrypt(i);return JSON.parse(s)},async set(e,i){let s=JSON.stringify(c===void 0?i:c(i));await t.setItem(a(e),await n.encrypt(s))},async remove(e){await t.removeItem(a(e))},async keys(e){let i=await t.keys(),s=o===""?i:i.filter((y)=>y.startsWith(o)).map(m);return e===void 0?s:s.filter((y)=>y.startsWith(e))},async clear(){await t.clear()}}}export{k as createKeyedStorage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StoragePort } from './port.js';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory {@link StoragePort} default for the B1a synchronous engine and
|
|
4
|
+
* tests. Non-durable (lost on restart) — durable platform variants land in
|
|
5
|
+
* B1b/#7.
|
|
6
|
+
*
|
|
7
|
+
* Values are structurally cloned on write and read so callers cannot mutate
|
|
8
|
+
* stored state by reference, matching the isolation a serializing durable store
|
|
9
|
+
* provides.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createMemoryStorage(): StoragePort;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
function o(){let r=new Map;return{get:async(e)=>{let n=r.get(e);return n===void 0?void 0:structuredClone(n)},set:async(e,n)=>{r.set(e,structuredClone(n))},remove:async(e)=>{r.delete(e)},keys:async(e)=>{let n=[...r.keys()];return e===void 0?n:n.filter((t)=>t.startsWith(e))},clear:async()=>{r.clear()}}}export{o as createMemoryStorage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable key/value storage port — the I/O-free contract behind which platform
|
|
3
|
+
* defaults live (in-memory for B1a; IndexedDB on web and SQLite/AsyncStorage on
|
|
4
|
+
* native in B1b/#7). It is intentionally value-agnostic: the engine layers the
|
|
5
|
+
* cache-entry and mutation-queue shapes on top, namespacing by key prefix.
|
|
6
|
+
*
|
|
7
|
+
* Implementations persist JSON-serializable values and own
|
|
8
|
+
* serialization, secret redaction, and the encryption-at-rest seam (AC12);
|
|
9
|
+
* the contract here stays free of any concrete I/O.
|
|
10
|
+
*/
|
|
11
|
+
export interface StoragePort {
|
|
12
|
+
/** Read a value by key, or `undefined` when absent. */
|
|
13
|
+
get<TValue = unknown>(key: string): Promise<TValue | undefined>;
|
|
14
|
+
/** Write (overwrite) a value by key. */
|
|
15
|
+
set<TValue = unknown>(key: string, value: TValue): Promise<void>;
|
|
16
|
+
/** Remove a single key. No-op when absent. */
|
|
17
|
+
remove(key: string): Promise<void>;
|
|
18
|
+
/** Enumerate keys, optionally filtered by prefix (used by GC + queue scans). */
|
|
19
|
+
keys(prefix?: string): Promise<readonly string[]>;
|
|
20
|
+
/** Remove every key in the store. */
|
|
21
|
+
clear(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export declare const storagePortDoc: {
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
summary: string;
|
|
27
|
+
kind: "reference";
|
|
28
|
+
visibility: "internal";
|
|
29
|
+
route: string;
|
|
30
|
+
domain: string;
|
|
31
|
+
owners: string[];
|
|
32
|
+
tags: string[];
|
|
33
|
+
body: string;
|
|
34
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var e={id:"docs.contracts-runtime-core.storage-port",title:"Durable storage port (I/O-free contract)",summary:"Value-agnostic durable key/value port; platform impls own serialization, redaction, and encryption-at-rest.",kind:"reference",visibility:"internal",route:"/docs/contracts-runtime-core/storage-port",domain:"contracts-runtime-core",owners:["@contractspec-core"],tags:["contracts-runtime-core","storage","persistence","port"],body:"Durable key/value StoragePort: get/set/remove/keys/clear. Intentionally value-agnostic \u2014 the engine layers CacheEntry and MutationQueueEntry shapes on top and namespaces by key prefix. keys(prefix?) supports GC and offline-queue scans. Implementations persist JSON-serializable values and own serialization, per-contract secret redaction, and the encryption-at-rest seam (AC12). B1a ships an in-memory default (createMemoryStorage); IndexedDB (web) and SQLite/AsyncStorage (native) platform variants land in B1b/#7 behind this same contract."};export{e as storagePortDoc};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { QueryEnvelope, QueryResultEnvelope } from '@lssm/lib.contracts-spec/query/envelope';
|
|
2
|
+
import type { InvalidationTag } from '@lssm/lib.contracts-spec/query/invalidation';
|
|
3
|
+
import type { VersionToken } from '@lssm/lib.contracts-spec/query/version-token';
|
|
4
|
+
import type { ContractResult } from '@lssm/lib.contracts-spec/results';
|
|
5
|
+
/**
|
|
6
|
+
* Per-call context threaded through a transport. The `principal` is opaque to
|
|
7
|
+
* the engine and every adapter: it is carried end-to-end unchanged and MUST
|
|
8
|
+
* NOT be stripped by the canonical envelope/result path (AC14). Enforcement of
|
|
9
|
+
* `policy.auth` stays in authos/identity-rbac, not here.
|
|
10
|
+
*/
|
|
11
|
+
export interface TransportContext {
|
|
12
|
+
/** Opaque auth principal / session token. Carried through, never inspected by core. */
|
|
13
|
+
principal?: unknown;
|
|
14
|
+
/** Correlation id for observability + tracing. */
|
|
15
|
+
correlationId?: string;
|
|
16
|
+
/** Cooperative cancellation signal. */
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
/** Transport-specific request metadata (e.g. headers). */
|
|
19
|
+
meta?: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A server-pushed invalidation notification. The per-entity `versionToken`
|
|
23
|
+
* doubles as the realtime invalidation token, so realtime delivery and
|
|
24
|
+
* optimistic-concurrency detection share one vocabulary.
|
|
25
|
+
*/
|
|
26
|
+
export interface InvalidationEvent {
|
|
27
|
+
tags: readonly InvalidationTag[];
|
|
28
|
+
versionToken?: VersionToken;
|
|
29
|
+
}
|
|
30
|
+
/** Handler invoked when subscribed tags are invalidated. */
|
|
31
|
+
export type InvalidationHandler = (event: InvalidationEvent) => void;
|
|
32
|
+
/**
|
|
33
|
+
* The single `Transport` port. REST, MCP, WebSocket, and in-memory are
|
|
34
|
+
* interchangeable adapters behind it; clients/providers never invent parallel
|
|
35
|
+
* envelopes. `subscribe` is the realtime seam — defined now, full delivery is a
|
|
36
|
+
* follow-on (the worker migration consumes this seam in Phase 7).
|
|
37
|
+
*/
|
|
38
|
+
export interface Transport {
|
|
39
|
+
execute<TInput = unknown, TData = unknown>(envelope: QueryEnvelope<TInput>, ctx?: TransportContext): Promise<ContractResult<QueryResultEnvelope<TData>>>;
|
|
40
|
+
subscribe?(tags: readonly InvalidationTag[], handler: InvalidationHandler): () => void;
|
|
41
|
+
}
|
|
42
|
+
export declare const transportPortDoc: {
|
|
43
|
+
id: string;
|
|
44
|
+
title: string;
|
|
45
|
+
summary: string;
|
|
46
|
+
kind: "reference";
|
|
47
|
+
visibility: "internal";
|
|
48
|
+
route: string;
|
|
49
|
+
domain: string;
|
|
50
|
+
owners: string[];
|
|
51
|
+
tags: string[];
|
|
52
|
+
body: string;
|
|
53
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var e={id:"docs.contracts-runtime-core.transport",title:"Transport port + absorbed data-transmission concept map",summary:"One Transport port carries the canonical protocol; each former data-transmission concept has an explicit home.",kind:"reference",visibility:"internal",route:"/docs/contracts-runtime-core/transport",domain:"contracts-runtime-core",owners:["@contractspec-core"],tags:["contracts-runtime-core","transport","data-transmission","port"],body:["The single Transport port: execute(envelope, ctx) \u2192 Promise<ContractResult<QueryResultEnvelope>>, plus an optional subscribe(tags, handler) realtime seam. REST/MCP/WebSocket/in-memory are interchangeable adapters behind it.","","Absorbed data-transmission concept map (each former concept has exactly one explicit home \u2014 no parallel transport types):","- idempotency \u2192 ContractResult success field (ContractResultIdempotency{key,replayed?,firstSeenAt?} on ContractSuccess.idempotency). NOT a transport argument.","- subscriptions \u2192 Transport.subscribe(tags, handler) seam (no spec type, by design); the version token doubles as the realtime invalidation token. Full delivery is a follow-on; the realtime worker migrates onto this seam in Phase 7.","- invalidation \u2192 the InvalidationTag{entity,id?} vocabulary (contracts-spec/query/invalidation) shared by optimistic updates, offline-queue replay, and realtime broadcast; mutations declare the tags they invalidate.","- consistency levels \u2192 the typed QueryEnvelope.consistency request field and ContractSuccess.consistency applied field (QueryConsistency = eventual | read-your-writes | strong, default read-your-writes). Typed, never prose. Subsumes the former DataFetchConsistency incl. read-your-writes.","","TransportContext.principal is opaque and carried end-to-end unchanged (AC14, no-strip); policy.auth enforcement stays in authos/identity-rbac."].join(`
|
|
3
|
+
`)};export{e as transportPortDoc};
|
package/package.json
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lssm/lib.contracts-runtime-core",
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"description": "Framework-neutral in-house query/cache/offline engine and Transport port for ContractSpec data fetching",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"contractspec",
|
|
7
|
+
"contracts",
|
|
8
|
+
"runtime",
|
|
9
|
+
"transport",
|
|
10
|
+
"cache",
|
|
11
|
+
"offline",
|
|
12
|
+
"core",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
|
|
19
|
+
"publish:pkg:canary": "bun publish:pkg --tag canary",
|
|
20
|
+
"build": "contractspec-bun-build build",
|
|
21
|
+
"build:bundle": "contractspec-bun-build transpile",
|
|
22
|
+
"build:types": "contractspec-bun-build types",
|
|
23
|
+
"clean": "rimraf dist .turbo",
|
|
24
|
+
"dev": "contractspec-bun-build dev",
|
|
25
|
+
"lint": "bun run lint:fix",
|
|
26
|
+
"lint:fix": "node ../../../scripts/biome.cjs check --write --unsafe --only=nursery/useSortedClasses . && node ../../../scripts/biome.cjs check --write .",
|
|
27
|
+
"lint:check": "node ../../../scripts/biome.cjs check .",
|
|
28
|
+
"prebuild": "contractspec-bun-build prebuild",
|
|
29
|
+
"smoke:exports": "node scripts/smoke-approval-exports.mjs --mode=artifact",
|
|
30
|
+
"smoke:exports:runtime": "node scripts/smoke-approval-exports.mjs --mode=runtime --entry=dist/index.js",
|
|
31
|
+
"typecheck": "tsgo --noEmit -p tsconfig.json"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"typescript": "^7.0.2 || ^6.0.3"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@lssm/lib.contracts-spec": "^17.3.2",
|
|
38
|
+
"@lssm/lib.observability": "^5.0.2"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@lssm-tech/tool.bun": "5.0.3",
|
|
42
|
+
"@lssm-tech/tool.typescript": "5.0.1",
|
|
43
|
+
"typescript": "^7.0.2"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"README.md"
|
|
48
|
+
],
|
|
49
|
+
"exports": {
|
|
50
|
+
".": {
|
|
51
|
+
"types": "./dist/index.d.ts",
|
|
52
|
+
"browser": "./dist/browser/index.js",
|
|
53
|
+
"bun": "./dist/index.js",
|
|
54
|
+
"node": "./dist/node/index.js",
|
|
55
|
+
"default": "./dist/index.js"
|
|
56
|
+
},
|
|
57
|
+
"./contracts-runtime-core.feature": {
|
|
58
|
+
"types": "./dist/contracts-runtime-core.feature.d.ts",
|
|
59
|
+
"browser": "./dist/browser/contracts-runtime-core.feature.js",
|
|
60
|
+
"bun": "./dist/contracts-runtime-core.feature.js",
|
|
61
|
+
"node": "./dist/node/contracts-runtime-core.feature.js",
|
|
62
|
+
"default": "./dist/contracts-runtime-core.feature.js"
|
|
63
|
+
},
|
|
64
|
+
"./observability": {
|
|
65
|
+
"types": "./dist/observability.d.ts",
|
|
66
|
+
"browser": "./dist/browser/observability.js",
|
|
67
|
+
"bun": "./dist/observability.js",
|
|
68
|
+
"node": "./dist/node/observability.js",
|
|
69
|
+
"default": "./dist/observability.js"
|
|
70
|
+
},
|
|
71
|
+
"./storage/async-storage": {
|
|
72
|
+
"types": "./dist/storage/async-storage.native.d.ts",
|
|
73
|
+
"react-native": "./dist/native/storage/async-storage.native.js",
|
|
74
|
+
"default": "./dist/native/storage/async-storage.native.js"
|
|
75
|
+
},
|
|
76
|
+
"./storage/indexeddb": {
|
|
77
|
+
"types": "./dist/storage/indexeddb.web.d.ts",
|
|
78
|
+
"browser": "./dist/browser/storage/indexeddb.web.js",
|
|
79
|
+
"default": "./dist/storage/indexeddb.web.js"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"publishConfig": {
|
|
83
|
+
"access": "public",
|
|
84
|
+
"exports": {
|
|
85
|
+
".": {
|
|
86
|
+
"types": "./dist/index.d.ts",
|
|
87
|
+
"browser": "./dist/browser/index.js",
|
|
88
|
+
"bun": "./dist/index.js",
|
|
89
|
+
"node": "./dist/node/index.js",
|
|
90
|
+
"default": "./dist/index.js"
|
|
91
|
+
},
|
|
92
|
+
"./contracts-runtime-core.feature": {
|
|
93
|
+
"types": "./dist/contracts-runtime-core.feature.d.ts",
|
|
94
|
+
"browser": "./dist/browser/contracts-runtime-core.feature.js",
|
|
95
|
+
"bun": "./dist/contracts-runtime-core.feature.js",
|
|
96
|
+
"node": "./dist/node/contracts-runtime-core.feature.js",
|
|
97
|
+
"default": "./dist/contracts-runtime-core.feature.js"
|
|
98
|
+
},
|
|
99
|
+
"./observability": {
|
|
100
|
+
"types": "./dist/observability.d.ts",
|
|
101
|
+
"browser": "./dist/browser/observability.js",
|
|
102
|
+
"bun": "./dist/observability.js",
|
|
103
|
+
"node": "./dist/node/observability.js",
|
|
104
|
+
"default": "./dist/observability.js"
|
|
105
|
+
},
|
|
106
|
+
"./storage/async-storage": {
|
|
107
|
+
"types": "./dist/storage/async-storage.native.d.ts",
|
|
108
|
+
"react-native": "./dist/native/storage/async-storage.native.js",
|
|
109
|
+
"default": "./dist/native/storage/async-storage.native.js"
|
|
110
|
+
},
|
|
111
|
+
"./storage/indexeddb": {
|
|
112
|
+
"types": "./dist/storage/indexeddb.web.d.ts",
|
|
113
|
+
"browser": "./dist/browser/storage/indexeddb.web.js",
|
|
114
|
+
"default": "./dist/storage/indexeddb.web.js"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"registry": "https://registry.npmjs.org"
|
|
118
|
+
},
|
|
119
|
+
"license": "MIT",
|
|
120
|
+
"repository": {
|
|
121
|
+
"type": "git",
|
|
122
|
+
"url": "https://github.com/lssm-tech/contractspec.git",
|
|
123
|
+
"directory": "packages/libs/contracts-runtime-core"
|
|
124
|
+
},
|
|
125
|
+
"homepage": "https://contractspec.io",
|
|
126
|
+
"contractspec": {
|
|
127
|
+
"catalog": {
|
|
128
|
+
"family": "runtime",
|
|
129
|
+
"kind": "library",
|
|
130
|
+
"status": "active",
|
|
131
|
+
"adoptionMode": "adoptable",
|
|
132
|
+
"stability": "stable",
|
|
133
|
+
"platforms": [
|
|
134
|
+
"server"
|
|
135
|
+
],
|
|
136
|
+
"runtimes": [
|
|
137
|
+
"node"
|
|
138
|
+
],
|
|
139
|
+
"entrypoints": [
|
|
140
|
+
".",
|
|
141
|
+
"./contracts-runtime-core.feature",
|
|
142
|
+
"./observability",
|
|
143
|
+
"./storage/async-storage",
|
|
144
|
+
"./storage/indexeddb"
|
|
145
|
+
],
|
|
146
|
+
"documentation": [
|
|
147
|
+
{
|
|
148
|
+
"title": "Lib Contracts Runtime Core documentation",
|
|
149
|
+
"url": "https://www.npmjs.com/package/%40lssm%2Flib.contracts-runtime-core",
|
|
150
|
+
"kind": "readme"
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"examples": [],
|
|
154
|
+
"replacements": [],
|
|
155
|
+
"capabilities": [
|
|
156
|
+
{
|
|
157
|
+
"id": "package.lssm.tech.lib.contracts.runtime.core",
|
|
158
|
+
"title": "Lib Contracts Runtime Core",
|
|
159
|
+
"description": "Framework-neutral in-house query/cache/offline engine and Transport port for ContractSpec data fetching",
|
|
160
|
+
"status": "active",
|
|
161
|
+
"useCases": [
|
|
162
|
+
"Adopt framework-neutral in-house query/cache/offline engine and transport port for contractspec data fetching"
|
|
163
|
+
],
|
|
164
|
+
"aliases": [
|
|
165
|
+
"contractspec",
|
|
166
|
+
"contracts",
|
|
167
|
+
"runtime",
|
|
168
|
+
"transport",
|
|
169
|
+
"cache",
|
|
170
|
+
"offline",
|
|
171
|
+
"core",
|
|
172
|
+
"typescript",
|
|
173
|
+
"lib"
|
|
174
|
+
],
|
|
175
|
+
"pythonEquivalents": [],
|
|
176
|
+
"canonicalImports": [
|
|
177
|
+
{
|
|
178
|
+
"from": "@lssm/lib.contracts-runtime-core",
|
|
179
|
+
"symbols": []
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"from": "@lssm/lib.contracts-runtime-core/contracts-runtime-core.feature",
|
|
183
|
+
"symbols": []
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"from": "@lssm/lib.contracts-runtime-core/observability",
|
|
187
|
+
"symbols": []
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"from": "@lssm/lib.contracts-runtime-core/storage/async-storage",
|
|
191
|
+
"symbols": []
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"from": "@lssm/lib.contracts-runtime-core/storage/indexeddb",
|
|
195
|
+
"symbols": []
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
"constraints": {
|
|
199
|
+
"platforms": [
|
|
200
|
+
"server"
|
|
201
|
+
],
|
|
202
|
+
"runtimes": [
|
|
203
|
+
"node"
|
|
204
|
+
],
|
|
205
|
+
"avoidWhen": [
|
|
206
|
+
"The @lssm/lib.contracts-runtime-core package constraints do not match the target runtime or platform."
|
|
207
|
+
],
|
|
208
|
+
"requires": [
|
|
209
|
+
"TypeScript"
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"alternatives": [],
|
|
213
|
+
"relationships": [],
|
|
214
|
+
"resolutionPriority": 50
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|