@stigmer/server 3.24.0 → 3.26.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/authorization/authorizer.d.ts +10 -4
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +11 -4
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/model/index.d.ts +4 -4
- package/dist/authorization/model/index.d.ts.map +1 -1
- package/dist/authorization/model/index.js +2 -0
- package/dist/authorization/model/index.js.map +1 -1
- package/dist/authorization/model/oauth_app.d.ts.map +1 -1
- package/dist/authorization/model/oauth_app.js +3 -2
- package/dist/authorization/model/oauth_app.js.map +1 -1
- package/dist/authorization/model/platform_client.d.ts +2 -0
- package/dist/authorization/model/platform_client.d.ts.map +1 -0
- package/dist/authorization/model/platform_client.js +31 -0
- package/dist/authorization/model/platform_client.js.map +1 -0
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +99 -13
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/list-indexes.d.ts +3 -0
- package/dist/boot/list-indexes.d.ts.map +1 -0
- package/dist/boot/list-indexes.js +24 -0
- package/dist/boot/list-indexes.js.map +1 -0
- package/dist/boot/route-shadowing.d.ts +25 -0
- package/dist/boot/route-shadowing.d.ts.map +1 -0
- package/dist/boot/route-shadowing.js +17 -0
- package/dist/boot/route-shadowing.js.map +1 -0
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +6 -8
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentexecution/list-index.d.ts +2 -0
- package/dist/domain/agentexecution/list-index.d.ts.map +1 -0
- package/dist/domain/agentexecution/list-index.js +23 -0
- package/dist/domain/agentexecution/list-index.js.map +1 -0
- package/dist/domain/agentexecution/steps.d.ts +17 -33
- package/dist/domain/agentexecution/steps.d.ts.map +1 -1
- package/dist/domain/agentexecution/steps.js +94 -95
- package/dist/domain/agentexecution/steps.js.map +1 -1
- package/dist/domain/agentexecution/usage.d.ts.map +1 -1
- package/dist/domain/agentexecution/usage.js +37 -14
- package/dist/domain/agentexecution/usage.js.map +1 -1
- package/dist/domain/artifact/controller.d.ts.map +1 -1
- package/dist/domain/artifact/controller.js +27 -15
- package/dist/domain/artifact/controller.js.map +1 -1
- package/dist/domain/artifact/list-index.d.ts +2 -0
- package/dist/domain/artifact/list-index.d.ts.map +1 -0
- package/dist/domain/artifact/list-index.js +21 -0
- package/dist/domain/artifact/list-index.js.map +1 -0
- package/dist/domain/iampolicy/membership.d.ts +6 -1
- package/dist/domain/iampolicy/membership.d.ts.map +1 -1
- package/dist/domain/iampolicy/membership.js +8 -2
- package/dist/domain/iampolicy/membership.js.map +1 -1
- package/dist/domain/identityaccount/constants.d.ts +13 -0
- package/dist/domain/identityaccount/constants.d.ts.map +1 -1
- package/dist/domain/identityaccount/constants.js +17 -0
- package/dist/domain/identityaccount/constants.js.map +1 -1
- package/dist/domain/identityaccount/controller.d.ts +3 -1
- package/dist/domain/identityaccount/controller.d.ts.map +1 -1
- package/dist/domain/identityaccount/controller.js +15 -6
- package/dist/domain/identityaccount/controller.js.map +1 -1
- package/dist/domain/identityaccount/operator.d.ts.map +1 -1
- package/dist/domain/identityaccount/operator.js +1 -0
- package/dist/domain/identityaccount/operator.js.map +1 -1
- package/dist/domain/identityaccount/provisioning.d.ts +18 -0
- package/dist/domain/identityaccount/provisioning.d.ts.map +1 -1
- package/dist/domain/identityaccount/provisioning.js +1 -0
- package/dist/domain/identityaccount/provisioning.js.map +1 -1
- package/dist/domain/identityaccount/resource-store.js +9 -5
- package/dist/domain/identityaccount/resource-store.js.map +1 -1
- package/dist/domain/identityaccount/steps.d.ts +11 -2
- package/dist/domain/identityaccount/steps.d.ts.map +1 -1
- package/dist/domain/identityaccount/steps.js +42 -4
- package/dist/domain/identityaccount/steps.js.map +1 -1
- package/dist/domain/identityaccount/store-contract.d.ts.map +1 -1
- package/dist/domain/identityaccount/store-contract.js +33 -0
- package/dist/domain/identityaccount/store-contract.js.map +1 -1
- package/dist/domain/identityaccount/store.d.ts +7 -5
- package/dist/domain/identityaccount/store.d.ts.map +1 -1
- package/dist/domain/identityaccount/store.js.map +1 -1
- package/dist/domain/platform/controller.d.ts +10 -0
- package/dist/domain/platform/controller.d.ts.map +1 -1
- package/dist/domain/platform/controller.js +2 -1
- package/dist/domain/platform/controller.js.map +1 -1
- package/dist/domain/platformclient/constants.d.ts +60 -0
- package/dist/domain/platformclient/constants.d.ts.map +1 -0
- package/dist/domain/platformclient/constants.js +78 -0
- package/dist/domain/platformclient/constants.js.map +1 -0
- package/dist/domain/platformclient/controller.d.ts +59 -0
- package/dist/domain/platformclient/controller.d.ts.map +1 -0
- package/dist/domain/platformclient/controller.js +191 -0
- package/dist/domain/platformclient/controller.js.map +1 -0
- package/dist/domain/platformclient/credentials.d.ts +13 -0
- package/dist/domain/platformclient/credentials.d.ts.map +1 -0
- package/dist/domain/platformclient/credentials.js +56 -0
- package/dist/domain/platformclient/credentials.js.map +1 -0
- package/dist/domain/platformclient/mint.d.ts +23 -0
- package/dist/domain/platformclient/mint.d.ts.map +1 -0
- package/dist/domain/platformclient/mint.js +254 -0
- package/dist/domain/platformclient/mint.js.map +1 -0
- package/dist/domain/platformclient/origin-guard.d.ts +9 -0
- package/dist/domain/platformclient/origin-guard.d.ts.map +1 -0
- package/dist/domain/platformclient/origin-guard.js +81 -0
- package/dist/domain/platformclient/origin-guard.js.map +1 -0
- package/dist/domain/platformclient/resource-store.d.ts +4 -0
- package/dist/domain/platformclient/resource-store.d.ts.map +1 -0
- package/dist/domain/platformclient/resource-store.js +117 -0
- package/dist/domain/platformclient/resource-store.js.map +1 -0
- package/dist/domain/platformclient/steps.d.ts +51 -0
- package/dist/domain/platformclient/steps.d.ts.map +1 -0
- package/dist/domain/platformclient/steps.js +339 -0
- package/dist/domain/platformclient/steps.js.map +1 -0
- package/dist/domain/platformclient/store-contract.d.ts +8 -0
- package/dist/domain/platformclient/store-contract.d.ts.map +1 -0
- package/dist/domain/platformclient/store-contract.js +208 -0
- package/dist/domain/platformclient/store-contract.js.map +1 -0
- package/dist/domain/platformclient/store.d.ts +58 -0
- package/dist/domain/platformclient/store.d.ts.map +1 -0
- package/dist/domain/platformclient/store.js +13 -0
- package/dist/domain/platformclient/store.js.map +1 -0
- package/dist/domain/platformclient/system-managed.d.ts +18 -0
- package/dist/domain/platformclient/system-managed.d.ts.map +1 -0
- package/dist/domain/platformclient/system-managed.js +80 -0
- package/dist/domain/platformclient/system-managed.js.map +1 -0
- package/dist/domain/platformclient/token-controller.d.ts +11 -0
- package/dist/domain/platformclient/token-controller.d.ts.map +1 -0
- package/dist/domain/platformclient/token-controller.js +32 -0
- package/dist/domain/platformclient/token-controller.js.map +1 -0
- package/dist/domain/platformclient/verifier.d.ts +10 -0
- package/dist/domain/platformclient/verifier.d.ts.map +1 -0
- package/dist/domain/platformclient/verifier.js +76 -0
- package/dist/domain/platformclient/verifier.js.map +1 -0
- package/dist/domain/session/list-index.d.ts +4 -0
- package/dist/domain/session/list-index.d.ts.map +1 -0
- package/dist/domain/session/list-index.js +26 -0
- package/dist/domain/session/list-index.js.map +1 -0
- package/dist/domain/session/steps.d.ts +7 -8
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +76 -78
- package/dist/domain/session/steps.js.map +1 -1
- package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
- package/dist/domain/workflowexecution/controller.js +53 -55
- package/dist/domain/workflowexecution/controller.js.map +1 -1
- package/dist/domain/workflowexecution/execution-filter.d.ts +4 -0
- package/dist/domain/workflowexecution/execution-filter.d.ts.map +1 -1
- package/dist/domain/workflowexecution/execution-filter.js +11 -5
- package/dist/domain/workflowexecution/execution-filter.js.map +1 -1
- package/dist/domain/workflowexecution/get-execution-summary.d.ts.map +1 -1
- package/dist/domain/workflowexecution/get-execution-summary.js +23 -17
- package/dist/domain/workflowexecution/get-execution-summary.js.map +1 -1
- package/dist/domain/workflowexecution/list-index.d.ts +2 -0
- package/dist/domain/workflowexecution/list-index.d.ts.map +1 -0
- package/dist/domain/workflowexecution/list-index.js +21 -0
- package/dist/domain/workflowexecution/list-index.js.map +1 -0
- package/dist/domain/workflowexecution/list-pending-approvals.d.ts.map +1 -1
- package/dist/domain/workflowexecution/list-pending-approvals.js +69 -32
- package/dist/domain/workflowexecution/list-pending-approvals.js.map +1 -1
- package/dist/domain/workflowexecution/queries.d.ts +30 -4
- package/dist/domain/workflowexecution/queries.d.ts.map +1 -1
- package/dist/domain/workflowexecution/queries.js +76 -22
- package/dist/domain/workflowexecution/queries.js.map +1 -1
- package/dist/encryption/key-manager.d.ts +20 -3
- package/dist/encryption/key-manager.d.ts.map +1 -1
- package/dist/encryption/key-manager.js +64 -42
- package/dist/encryption/key-manager.js.map +1 -1
- package/dist/extensions/caller-guards.d.ts +8 -3
- package/dist/extensions/caller-guards.d.ts.map +1 -1
- package/dist/extensions/drivers.d.ts +37 -0
- package/dist/extensions/drivers.d.ts.map +1 -1
- package/dist/extensions/guest-token-minting.d.ts +26 -0
- package/dist/extensions/guest-token-minting.d.ts.map +1 -0
- package/dist/extensions/guest-token-minting.js +2 -0
- package/dist/extensions/guest-token-minting.js.map +1 -0
- package/dist/extensions/identity.d.ts +6 -4
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +9 -12
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/extensions/registry.d.ts +30 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/extensions/registry.js +34 -1
- package/dist/extensions/registry.js.map +1 -1
- package/dist/index.d.ts +15 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/interceptors/auth.d.ts +14 -0
- package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
- package/dist/pipeline/interceptors/auth.js +24 -0
- package/dist/pipeline/interceptors/auth.js.map +1 -1
- package/dist/pipeline/steps/build-update-state.d.ts +11 -1
- package/dist/pipeline/steps/build-update-state.d.ts.map +1 -1
- package/dist/pipeline/steps/build-update-state.js +5 -2
- package/dist/pipeline/steps/build-update-state.js.map +1 -1
- package/dist/pipeline/steps/list-page.d.ts +63 -0
- package/dist/pipeline/steps/list-page.d.ts.map +1 -0
- package/dist/pipeline/steps/list-page.js +187 -0
- package/dist/pipeline/steps/list-page.js.map +1 -0
- package/dist/platformtoken/envelope.d.ts +100 -0
- package/dist/platformtoken/envelope.d.ts.map +1 -0
- package/dist/platformtoken/envelope.js +184 -0
- package/dist/platformtoken/envelope.js.map +1 -0
- package/dist/platformtoken/key-ring.d.ts +85 -0
- package/dist/platformtoken/key-ring.d.ts.map +1 -0
- package/dist/platformtoken/key-ring.js +164 -0
- package/dist/platformtoken/key-ring.js.map +1 -0
- package/dist/query/activity/handler.d.ts +6 -7
- package/dist/query/activity/handler.d.ts.map +1 -1
- package/dist/query/activity/handler.js +42 -59
- package/dist/query/activity/handler.js.map +1 -1
- package/dist/store/interface.d.ts +29 -0
- package/dist/store/interface.d.ts.map +1 -1
- package/dist/store/interface.js.map +1 -1
- package/dist/store/list-index.d.ts +123 -0
- package/dist/store/list-index.d.ts.map +1 -0
- package/dist/store/list-index.js +277 -0
- package/dist/store/list-index.js.map +1 -0
- package/dist/store/logger.d.ts +3 -0
- package/dist/store/logger.d.ts.map +1 -1
- package/dist/store/logger.js +5 -1
- package/dist/store/logger.js.map +1 -1
- package/dist/store/postgres/migrations.d.ts +10 -6
- package/dist/store/postgres/migrations.d.ts.map +1 -1
- package/dist/store/postgres/migrations.js +64 -6
- package/dist/store/postgres/migrations.js.map +1 -1
- package/dist/store/postgres/store.d.ts +26 -5
- package/dist/store/postgres/store.d.ts.map +1 -1
- package/dist/store/postgres/store.js +377 -22
- package/dist/store/postgres/store.js.map +1 -1
- package/dist/store/sqlite/migrations.d.ts +11 -5
- package/dist/store/sqlite/migrations.d.ts.map +1 -1
- package/dist/store/sqlite/migrations.js +50 -4
- package/dist/store/sqlite/migrations.js.map +1 -1
- package/dist/store/sqlite/store.d.ts +18 -3
- package/dist/store/sqlite/store.d.ts.map +1 -1
- package/dist/store/sqlite/store.js +321 -15
- package/dist/store/sqlite/store.js.map +1 -1
- package/package.json +6 -6
- package/src/authorization/README.md +1 -1
- package/src/authorization/__tests__/authorizer.test.ts +6 -2
- package/src/authorization/__tests__/drivers.ts +6 -1
- package/src/authorization/__tests__/wire-permissions.test.ts +1 -0
- package/src/authorization/authorizer.ts +11 -4
- package/src/authorization/model/__tests__/registry.test.ts +8 -1
- package/src/authorization/model/index.ts +6 -4
- package/src/authorization/model/oauth_app.ts +3 -2
- package/src/authorization/model/platform_client.ts +43 -0
- package/src/boot/__tests__/auth-enabled-composition.test.ts +2 -1
- package/src/boot/__tests__/list-indexes.test.ts +65 -0
- package/src/boot/__tests__/route-shadowing.test.ts +67 -0
- package/src/boot/compose.ts +113 -18
- package/src/boot/list-indexes.ts +25 -0
- package/src/boot/route-shadowing.ts +47 -0
- package/src/domain/agentexecution/__tests__/agentexecution.test.ts +85 -3
- package/src/domain/agentexecution/controller.ts +8 -10
- package/src/domain/agentexecution/list-index.ts +24 -0
- package/src/domain/agentexecution/steps.ts +118 -115
- package/src/domain/agentexecution/usage.ts +38 -17
- package/src/domain/artifact/controller.ts +28 -18
- package/src/domain/artifact/list-index.ts +22 -0
- package/src/domain/iampolicy/__tests__/membership.test.ts +7 -0
- package/src/domain/iampolicy/membership.ts +8 -2
- package/src/domain/identityaccount/__tests__/platform-client-accounts.test.ts +124 -0
- package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -0
- package/src/domain/identityaccount/constants.ts +20 -0
- package/src/domain/identityaccount/controller.ts +16 -4
- package/src/domain/identityaccount/operator.ts +1 -0
- package/src/domain/identityaccount/provisioning.ts +17 -0
- package/src/domain/identityaccount/resource-store.ts +9 -5
- package/src/domain/identityaccount/steps.ts +58 -3
- package/src/domain/identityaccount/store-contract.ts +51 -0
- package/src/domain/identityaccount/store.ts +7 -5
- package/src/domain/platform/__tests__/platform.test.ts +7 -1
- package/src/domain/platform/controller.ts +12 -1
- package/src/domain/platformclient/__tests__/controller.test.ts +397 -0
- package/src/domain/platformclient/__tests__/credentials.test.ts +46 -0
- package/src/domain/platformclient/__tests__/mint.test.ts +415 -0
- package/src/domain/platformclient/__tests__/resource-store.test.ts +140 -0
- package/src/domain/platformclient/__tests__/system-managed.test.ts +101 -0
- package/src/domain/platformclient/__tests__/verifier-and-guard.test.ts +207 -0
- package/src/domain/platformclient/constants.ts +120 -0
- package/src/domain/platformclient/controller.ts +449 -0
- package/src/domain/platformclient/credentials.ts +68 -0
- package/src/domain/platformclient/mint.ts +412 -0
- package/src/domain/platformclient/origin-guard.ts +117 -0
- package/src/domain/platformclient/resource-store.ts +150 -0
- package/src/domain/platformclient/steps.ts +472 -0
- package/src/domain/platformclient/store-contract.ts +318 -0
- package/src/domain/platformclient/store.ts +63 -0
- package/src/domain/platformclient/system-managed.ts +115 -0
- package/src/domain/platformclient/token-controller.ts +49 -0
- package/src/domain/platformclient/verifier.ts +106 -0
- package/src/domain/session/list-index.ts +28 -0
- package/src/domain/session/steps.ts +108 -123
- package/src/domain/workflowexecution/__tests__/list-read-scope-summaries.test.ts +155 -99
- package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +193 -31
- package/src/domain/workflowexecution/controller.ts +54 -82
- package/src/domain/workflowexecution/execution-filter.ts +20 -7
- package/src/domain/workflowexecution/get-execution-summary.ts +31 -24
- package/src/domain/workflowexecution/list-index.ts +22 -0
- package/src/domain/workflowexecution/list-pending-approvals.ts +82 -25
- package/src/domain/workflowexecution/queries.ts +134 -23
- package/src/encryption/key-manager.ts +87 -44
- package/src/extensions/__tests__/extension-composition.test.ts +3 -2
- package/src/extensions/__tests__/platform-client-composed.test.ts +288 -0
- package/src/extensions/__tests__/registry.test.ts +4 -1
- package/src/extensions/__tests__/tier-truthfulness.test.ts +8 -0
- package/src/extensions/caller-guards.ts +8 -3
- package/src/extensions/drivers.ts +37 -0
- package/src/extensions/guest-token-minting.ts +32 -0
- package/src/extensions/identity.ts +6 -4
- package/src/extensions/list-read-scope.ts +9 -12
- package/src/extensions/registry.ts +77 -3
- package/src/index.ts +65 -1
- package/src/pipeline/interceptors/auth.ts +27 -0
- package/src/pipeline/steps/__tests__/list-page.test.ts +186 -0
- package/src/pipeline/steps/__tests__/references.test.ts +2 -0
- package/src/pipeline/steps/build-update-state.ts +5 -2
- package/src/pipeline/steps/list-page.ts +284 -0
- package/src/platformtoken/__tests__/envelope.test.ts +277 -0
- package/src/platformtoken/__tests__/key-ring.test.ts +205 -0
- package/src/platformtoken/envelope.ts +276 -0
- package/src/platformtoken/key-ring.ts +266 -0
- package/src/query/activity/handler.ts +57 -78
- package/src/runnerauth/__tests__/runner-subject-composed.test.ts +9 -3
- package/src/store/README.md +51 -32
- package/src/store/__tests__/list-index.measure.test.ts +293 -0
- package/src/store/__tests__/list-index.test.ts +328 -0
- package/src/store/__tests__/store-contract.ts +346 -3
- package/src/store/interface.ts +39 -0
- package/src/store/list-index.ts +465 -0
- package/src/store/logger.ts +8 -1
- package/src/store/postgres/__tests__/list-index-repair.test.ts +133 -0
- package/src/store/postgres/__tests__/migrations.test.ts +27 -19
- package/src/store/postgres/__tests__/store-contract.test.ts +50 -3
- package/src/store/postgres/migrations.ts +69 -7
- package/src/store/postgres/store.ts +485 -29
- package/src/store/sqlite/__tests__/migrations.test.ts +51 -7
- package/src/store/sqlite/__tests__/store-contract.test.ts +70 -16
- package/src/store/sqlite/__tests__/support.ts +12 -3
- package/src/store/sqlite/migrations.ts +57 -6
- package/src/store/sqlite/store.ts +462 -21
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { DescMessage } from "@bufbuild/protobuf";
|
|
2
|
+
import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
3
|
+
/** Where a list key's value is read from: a string field or a label. */
|
|
4
|
+
export type ListKeySource = {
|
|
5
|
+
readonly from: "field";
|
|
6
|
+
readonly path: string;
|
|
7
|
+
} | {
|
|
8
|
+
readonly from: "label";
|
|
9
|
+
readonly label: string;
|
|
10
|
+
};
|
|
11
|
+
/** A string field of the resource, by proto field names from the root ("spec.session_id"). */
|
|
12
|
+
export declare function field(path: string): ListKeySource;
|
|
13
|
+
/** A `metadata.labels` entry. */
|
|
14
|
+
export declare function label(key: string): ListKeySource;
|
|
15
|
+
/**
|
|
16
|
+
* One kind's list index. `revision` is bumped whenever `keys` changes, so
|
|
17
|
+
* rows written under another revision are re-derived rather than read
|
|
18
|
+
* through keys they may lack; boot/__tests__/list-indexes.test.ts pins
|
|
19
|
+
* every declaration's keys to its revision so a change cannot forget it.
|
|
20
|
+
*/
|
|
21
|
+
export interface ListIndexDeclaration<K extends string = string> {
|
|
22
|
+
readonly kind: ApiResourceKind;
|
|
23
|
+
readonly schema: DescMessage;
|
|
24
|
+
readonly revision: number;
|
|
25
|
+
readonly keys: Readonly<Record<K, ListKeySource>>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Declares a kind's list index, resolving every key against the schema so
|
|
29
|
+
* a misspelt path or a non-string field fails at module load, not as a
|
|
30
|
+
* silently empty list.
|
|
31
|
+
*/
|
|
32
|
+
export declare function declareListIndex<K extends string>(declaration: ListIndexDeclaration<K>): ListIndexDeclaration<K>;
|
|
33
|
+
/** The declaration's shape as text, for the revision pin. */
|
|
34
|
+
export declare function listIndexFingerprint(declaration: ListIndexDeclaration): string;
|
|
35
|
+
/** The facts a store keeps beside one row of a list-indexed kind. */
|
|
36
|
+
export interface ListIndexFacts {
|
|
37
|
+
readonly org: string;
|
|
38
|
+
readonly createdAt: string;
|
|
39
|
+
readonly revision: number;
|
|
40
|
+
readonly keys: ReadonlyArray<{
|
|
41
|
+
readonly key: string;
|
|
42
|
+
readonly value: string;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
interface TimestampShape {
|
|
46
|
+
readonly seconds: bigint;
|
|
47
|
+
readonly nanos: number;
|
|
48
|
+
}
|
|
49
|
+
/** Derives a decoded row's facts; every absence is the empty value, never a throw. */
|
|
50
|
+
export declare function listIndexFactsOf(declaration: ListIndexDeclaration, resource: object): ListIndexFacts;
|
|
51
|
+
/**
|
|
52
|
+
* Whether two derivations would write the same key rows — the check that
|
|
53
|
+
* lets an update skip rewriting them, which a status write never needs.
|
|
54
|
+
*/
|
|
55
|
+
export declare function sameListKeyRows(a: ListIndexFacts, b: ListIndexFacts): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* A timestamp as the index's fixed-width UTC text
|
|
58
|
+
* (`YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ`), or "" when absent.
|
|
59
|
+
*/
|
|
60
|
+
export declare function listIndexInstant(timestamp: TimestampShape | undefined): string;
|
|
61
|
+
/** Epoch milliseconds as the index's instant, for a `createdAtOrAfter` bound. */
|
|
62
|
+
export declare function listIndexInstantOfMillis(millis: number): string;
|
|
63
|
+
/** A position in the index's order: the last row a read handed out. */
|
|
64
|
+
export interface ListIndexCursor {
|
|
65
|
+
readonly createdAt: string;
|
|
66
|
+
readonly id: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* One indexed read. Every predicate is optional and they AND together;
|
|
70
|
+
* `anyKey` matches a row whose value for ANY listed key equals the given
|
|
71
|
+
* value (a workflow run names its workflow or its instance).
|
|
72
|
+
*/
|
|
73
|
+
export interface ListIndexQuery<K extends string = string> {
|
|
74
|
+
/** One organization's rows; "" or absent reads every organization. */
|
|
75
|
+
readonly org?: string;
|
|
76
|
+
readonly anyKey?: ReadonlyArray<{
|
|
77
|
+
readonly name: K;
|
|
78
|
+
readonly value: string;
|
|
79
|
+
}>;
|
|
80
|
+
/** Rows created at or after this instant, plus rows with no creation stamp. */
|
|
81
|
+
readonly createdAtOrAfter?: string;
|
|
82
|
+
/** Rows strictly after this position in the order. */
|
|
83
|
+
readonly after?: ListIndexCursor;
|
|
84
|
+
/** At most this many rows; absent reads every matching row. */
|
|
85
|
+
readonly limit?: number;
|
|
86
|
+
}
|
|
87
|
+
/** One row a read hands out, with its position for the next read. */
|
|
88
|
+
export interface ListIndexRow {
|
|
89
|
+
readonly id: string;
|
|
90
|
+
readonly data: Uint8Array;
|
|
91
|
+
readonly cursor: ListIndexCursor;
|
|
92
|
+
}
|
|
93
|
+
/** Negative when `a` comes first in the index's newest-first order. */
|
|
94
|
+
export declare function compareListIndexOrder(a: ListIndexCursor, b: ListIndexCursor): number;
|
|
95
|
+
/** Whether a row's facts satisfy a query's predicates, the cursor included. */
|
|
96
|
+
export declare function matchesListIndexQuery(id: string, facts: ListIndexFacts, query: ListIndexQuery): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* The drivers' last step: the proven rows the index answered, merged with
|
|
99
|
+
* the unproven rows evaluated from their bytes, in order, without
|
|
100
|
+
* duplicates, cut to the limit. Both inputs already satisfy the query.
|
|
101
|
+
*/
|
|
102
|
+
export declare function mergeListIndexRows(proven: ReadonlyArray<ListIndexRow>, unproven: ReadonlyArray<ListIndexRow>, limit: number | undefined): ListIndexRow[];
|
|
103
|
+
/** Refuses a limit a caller cannot mean: zero, negative or fractional. */
|
|
104
|
+
export declare function assertListIndexLimit(limit: number | undefined): void;
|
|
105
|
+
/**
|
|
106
|
+
* The declarations one store was opened with, keyed by kind. A read names
|
|
107
|
+
* its declaration and the store refuses one it was not opened with, so a
|
|
108
|
+
* lane and the composition root cannot silently disagree about an index.
|
|
109
|
+
*/
|
|
110
|
+
export declare class ListIndexRegistry {
|
|
111
|
+
private readonly byKind;
|
|
112
|
+
constructor(declarations: ReadonlyArray<ListIndexDeclaration>);
|
|
113
|
+
/** The declaration for a kind, or undefined when the kind is not list-indexed. */
|
|
114
|
+
declarationOf(kind: ApiResourceKind): ListIndexDeclaration | undefined;
|
|
115
|
+
/** Every declaration, in registration order. */
|
|
116
|
+
declarations(): ReadonlyArray<ListIndexDeclaration>;
|
|
117
|
+
/** A decoded row's facts when its kind is list-indexed; undefined otherwise. */
|
|
118
|
+
factsOf(kind: ApiResourceKind, resource: object): ListIndexFacts | undefined;
|
|
119
|
+
/** Throws unless this exact declaration was registered. */
|
|
120
|
+
require(declaration: ListIndexDeclaration): void;
|
|
121
|
+
}
|
|
122
|
+
export {};
|
|
123
|
+
//# sourceMappingURL=list-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-index.d.ts","sourceRoot":"","sources":["../../src/store/list-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The list index: what a store keeps beside a row so a list lane can read
|
|
3
|
+
* one organization's or one parent's rows in creation order without
|
|
4
|
+
* decoding the whole kind. Every list lane used to call `listResources`
|
|
5
|
+
* and filter in memory, and the payload is opaque bytes by contract
|
|
6
|
+
* (postgres/migrations.ts: audit hashes are content-addressed over them),
|
|
7
|
+
* so an index is projected columns written beside the blob, never a path
|
|
8
|
+
* into it.
|
|
9
|
+
*
|
|
10
|
+
* A kind is list-indexed exactly when its declaration appears in the one
|
|
11
|
+
* explicit list the composition root hands to the store when it opens
|
|
12
|
+
* (boot/list-indexes.ts) — the search registry's idiom
|
|
13
|
+
* (query/search/registry.ts). A declaration lives beside the lanes that
|
|
14
|
+
* filter on its keys (`domain/<kind>/list-index.ts`) and states them as
|
|
15
|
+
* data, a field path or a label, so the store derives them without
|
|
16
|
+
* knowing any domain: this module is the one derivation every writer, the
|
|
17
|
+
* reconciliation at open and every read of an unproven row share.
|
|
18
|
+
*
|
|
19
|
+
* Facts are written atomically with the row, never best-effort (the one
|
|
20
|
+
* deliberate divergence from search, whose index only degrades search: a
|
|
21
|
+
* missing list row hides a row). A row's facts are PROVEN current when
|
|
22
|
+
* its stamp equals its `updated_at` and its revision is its declaration's;
|
|
23
|
+
* a row written by a binary that does not know the index (every production
|
|
24
|
+
* roll overlaps the old and the new pod for a minute), or by one with
|
|
25
|
+
* another revision of the declaration, is UNPROVEN, and a read evaluates
|
|
26
|
+
* it from its bytes with this module and repairs it (`queryResources` in
|
|
27
|
+
* interface.ts states the contract). Exactness is therefore the store's
|
|
28
|
+
* guarantee, independent of timing.
|
|
29
|
+
*
|
|
30
|
+
* The order is one for every indexed read: newest first on the audit's
|
|
31
|
+
* `spec_audit.created_at`, ties broken by id, both compared as bytes. The
|
|
32
|
+
* instant is fixed-width UTC text so the drivers sort it as text and this
|
|
33
|
+
* module compares it the same way; an absent stamp is the empty string,
|
|
34
|
+
* which sorts last newest-first — exactly `compareCreatedAtDesc`
|
|
35
|
+
* (pipeline/steps/helpers.ts), the order the session lists always had.
|
|
36
|
+
*
|
|
37
|
+
* Proven by __tests__/list-index.test.ts (declaration validation, the
|
|
38
|
+
* derivation, the instant, the merge) and, per driver, by the list-index
|
|
39
|
+
* arms of __tests__/store-contract.ts.
|
|
40
|
+
*/
|
|
41
|
+
import { ScalarType } from "@bufbuild/protobuf";
|
|
42
|
+
import { apiResourceKindName } from "./proto-fields.js";
|
|
43
|
+
/** A string field of the resource, by proto field names from the root ("spec.session_id"). */
|
|
44
|
+
export function field(path) {
|
|
45
|
+
return { from: "field", path };
|
|
46
|
+
}
|
|
47
|
+
/** A `metadata.labels` entry. */
|
|
48
|
+
export function label(key) {
|
|
49
|
+
return { from: "label", label: key };
|
|
50
|
+
}
|
|
51
|
+
const resolvedKeys = new WeakMap();
|
|
52
|
+
/**
|
|
53
|
+
* Declares a kind's list index, resolving every key against the schema so
|
|
54
|
+
* a misspelt path or a non-string field fails at module load, not as a
|
|
55
|
+
* silently empty list.
|
|
56
|
+
*/
|
|
57
|
+
export function declareListIndex(declaration) {
|
|
58
|
+
if (!Number.isInteger(declaration.revision) || declaration.revision < 1) {
|
|
59
|
+
throw new Error(`list index for ${apiResourceKindName(declaration.kind)}: revision must be a positive integer`);
|
|
60
|
+
}
|
|
61
|
+
const keys = [];
|
|
62
|
+
for (const [name, source] of Object.entries(declaration.keys)) {
|
|
63
|
+
keys.push({ name, read: resolveKeyReader(declaration, name, source) });
|
|
64
|
+
}
|
|
65
|
+
const frozen = Object.freeze({
|
|
66
|
+
...declaration,
|
|
67
|
+
keys: Object.freeze({ ...declaration.keys }),
|
|
68
|
+
});
|
|
69
|
+
resolvedKeys.set(frozen, keys);
|
|
70
|
+
return frozen;
|
|
71
|
+
}
|
|
72
|
+
function resolveKeyReader(declaration, name, source) {
|
|
73
|
+
switch (source.from) {
|
|
74
|
+
case "label":
|
|
75
|
+
return (resource) => resource.metadata?.labels?.[source.label] ?? "";
|
|
76
|
+
case "field": {
|
|
77
|
+
const localNames = resolveFieldPath(declaration, name, source.path);
|
|
78
|
+
return (resource) => {
|
|
79
|
+
let value = resource;
|
|
80
|
+
for (const localName of localNames) {
|
|
81
|
+
if (value === null || typeof value !== "object") {
|
|
82
|
+
return "";
|
|
83
|
+
}
|
|
84
|
+
value = value[localName];
|
|
85
|
+
}
|
|
86
|
+
return typeof value === "string" ? value : "";
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
default: {
|
|
90
|
+
const exhaustive = source;
|
|
91
|
+
throw new Error(`unknown list key source: ${String(exhaustive)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function resolveFieldPath(declaration, name, path) {
|
|
96
|
+
const where = `list index for ${apiResourceKindName(declaration.kind)}, key '${name}'`;
|
|
97
|
+
const segments = path.split(".");
|
|
98
|
+
const localNames = [];
|
|
99
|
+
let message = declaration.schema;
|
|
100
|
+
segments.forEach((segment, index) => {
|
|
101
|
+
const found = message?.fields.find((f) => f.name === segment);
|
|
102
|
+
if (found === undefined) {
|
|
103
|
+
throw new Error(`${where}: '${path}' has no field '${segment}'`);
|
|
104
|
+
}
|
|
105
|
+
localNames.push(found.localName);
|
|
106
|
+
const last = index === segments.length - 1;
|
|
107
|
+
if (last) {
|
|
108
|
+
if (found.fieldKind !== "scalar" || found.scalar !== ScalarType.STRING) {
|
|
109
|
+
throw new Error(`${where}: '${path}' is not a string field`);
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (found.fieldKind !== "message") {
|
|
114
|
+
throw new Error(`${where}: '${segment}' in '${path}' is not a message`);
|
|
115
|
+
}
|
|
116
|
+
message = found.message;
|
|
117
|
+
});
|
|
118
|
+
return localNames;
|
|
119
|
+
}
|
|
120
|
+
/** The declaration's shape as text, for the revision pin. */
|
|
121
|
+
export function listIndexFingerprint(declaration) {
|
|
122
|
+
const keys = Object.entries(declaration.keys)
|
|
123
|
+
.map(([name, source]) => source.from === "field"
|
|
124
|
+
? `${name}=field:${source.path}`
|
|
125
|
+
: `${name}=label:${source.label}`)
|
|
126
|
+
.sort();
|
|
127
|
+
return `${apiResourceKindName(declaration.kind)}{${keys.join(",")}}`;
|
|
128
|
+
}
|
|
129
|
+
/** Derives a decoded row's facts; every absence is the empty value, never a throw. */
|
|
130
|
+
export function listIndexFactsOf(declaration, resource) {
|
|
131
|
+
const shaped = resource;
|
|
132
|
+
const keys = [];
|
|
133
|
+
for (const resolved of keysOf(declaration)) {
|
|
134
|
+
const value = resolved.read(resource);
|
|
135
|
+
if (value !== "") {
|
|
136
|
+
keys.push({ key: resolved.name, value });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
org: shaped.metadata?.org ?? "",
|
|
141
|
+
createdAt: listIndexInstant(shaped.status?.audit?.specAudit?.createdAt),
|
|
142
|
+
revision: declaration.revision,
|
|
143
|
+
keys,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Whether two derivations would write the same key rows — the check that
|
|
148
|
+
* lets an update skip rewriting them, which a status write never needs.
|
|
149
|
+
*/
|
|
150
|
+
export function sameListKeyRows(a, b) {
|
|
151
|
+
return (a.createdAt === b.createdAt &&
|
|
152
|
+
a.keys.length === b.keys.length &&
|
|
153
|
+
a.keys.every((k, i) => k.key === b.keys[i]?.key && k.value === b.keys[i]?.value));
|
|
154
|
+
}
|
|
155
|
+
function keysOf(declaration) {
|
|
156
|
+
const keys = resolvedKeys.get(declaration);
|
|
157
|
+
if (keys === undefined) {
|
|
158
|
+
throw new Error(`list index for ${apiResourceKindName(declaration.kind)} was not made by declareListIndex`);
|
|
159
|
+
}
|
|
160
|
+
return keys;
|
|
161
|
+
}
|
|
162
|
+
// The instant is representable as four-digit-year ISO text in this range;
|
|
163
|
+
// outside it a stamp is treated as absent rather than mis-sorted.
|
|
164
|
+
const MIN_INSTANT_SECONDS = -62135596800n; // 0001-01-01T00:00:00Z
|
|
165
|
+
const MAX_INSTANT_SECONDS = 253402300799n; // 9999-12-31T23:59:59Z
|
|
166
|
+
/**
|
|
167
|
+
* A timestamp as the index's fixed-width UTC text
|
|
168
|
+
* (`YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ`), or "" when absent.
|
|
169
|
+
*/
|
|
170
|
+
export function listIndexInstant(timestamp) {
|
|
171
|
+
if (timestamp === undefined ||
|
|
172
|
+
timestamp.seconds < MIN_INSTANT_SECONDS ||
|
|
173
|
+
timestamp.seconds > MAX_INSTANT_SECONDS) {
|
|
174
|
+
return "";
|
|
175
|
+
}
|
|
176
|
+
const iso = new Date(Number(timestamp.seconds) * 1000).toISOString();
|
|
177
|
+
const nanos = String(Math.max(0, Math.min(999_999_999, timestamp.nanos))).padStart(9, "0");
|
|
178
|
+
return `${iso.slice(0, 19)}.${nanos}Z`;
|
|
179
|
+
}
|
|
180
|
+
/** Epoch milliseconds as the index's instant, for a `createdAtOrAfter` bound. */
|
|
181
|
+
export function listIndexInstantOfMillis(millis) {
|
|
182
|
+
const seconds = Math.floor(millis / 1000);
|
|
183
|
+
const nanos = (millis - seconds * 1000) * 1_000_000;
|
|
184
|
+
return listIndexInstant({ seconds: BigInt(seconds), nanos });
|
|
185
|
+
}
|
|
186
|
+
/** Byte order, the order both drivers sort text in (Postgres `COLLATE "C"`, sqlite BINARY). */
|
|
187
|
+
function compareBytes(a, b) {
|
|
188
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
189
|
+
}
|
|
190
|
+
/** Negative when `a` comes first in the index's newest-first order. */
|
|
191
|
+
export function compareListIndexOrder(a, b) {
|
|
192
|
+
const byCreated = compareBytes(b.createdAt, a.createdAt);
|
|
193
|
+
return byCreated !== 0 ? byCreated : compareBytes(b.id, a.id);
|
|
194
|
+
}
|
|
195
|
+
/** Whether a row's facts satisfy a query's predicates, the cursor included. */
|
|
196
|
+
export function matchesListIndexQuery(id, facts, query) {
|
|
197
|
+
if (query.org !== undefined && query.org !== "" && facts.org !== query.org) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
if (query.anyKey !== undefined) {
|
|
201
|
+
const wanted = query.anyKey;
|
|
202
|
+
if (!facts.keys.some((k) => wanted.some((w) => w.name === k.key && w.value === k.value))) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (query.createdAtOrAfter !== undefined &&
|
|
207
|
+
facts.createdAt !== "" &&
|
|
208
|
+
compareBytes(facts.createdAt, query.createdAtOrAfter) < 0) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
if (query.after !== undefined &&
|
|
212
|
+
compareListIndexOrder({ createdAt: facts.createdAt, id }, query.after) <= 0) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* The drivers' last step: the proven rows the index answered, merged with
|
|
219
|
+
* the unproven rows evaluated from their bytes, in order, without
|
|
220
|
+
* duplicates, cut to the limit. Both inputs already satisfy the query.
|
|
221
|
+
*/
|
|
222
|
+
export function mergeListIndexRows(proven, unproven, limit) {
|
|
223
|
+
const byId = new Map();
|
|
224
|
+
for (const row of [...proven, ...unproven]) {
|
|
225
|
+
byId.set(row.id, row);
|
|
226
|
+
}
|
|
227
|
+
const merged = [...byId.values()].sort((a, b) => compareListIndexOrder(a.cursor, b.cursor));
|
|
228
|
+
return limit === undefined ? merged : merged.slice(0, limit);
|
|
229
|
+
}
|
|
230
|
+
/** Refuses a limit a caller cannot mean: zero, negative or fractional. */
|
|
231
|
+
export function assertListIndexLimit(limit) {
|
|
232
|
+
if (limit !== undefined && (!Number.isInteger(limit) || limit < 1)) {
|
|
233
|
+
throw new Error(`list index limit must be a positive integer, got ${limit}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// =============================================================================
|
|
237
|
+
// The registry a store opens with
|
|
238
|
+
// =============================================================================
|
|
239
|
+
/**
|
|
240
|
+
* The declarations one store was opened with, keyed by kind. A read names
|
|
241
|
+
* its declaration and the store refuses one it was not opened with, so a
|
|
242
|
+
* lane and the composition root cannot silently disagree about an index.
|
|
243
|
+
*/
|
|
244
|
+
export class ListIndexRegistry {
|
|
245
|
+
byKind = new Map();
|
|
246
|
+
constructor(declarations) {
|
|
247
|
+
for (const declaration of declarations) {
|
|
248
|
+
keysOf(declaration);
|
|
249
|
+
if (this.byKind.has(declaration.kind)) {
|
|
250
|
+
throw new Error(`list index for ${apiResourceKindName(declaration.kind)} is declared twice`);
|
|
251
|
+
}
|
|
252
|
+
this.byKind.set(declaration.kind, declaration);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/** The declaration for a kind, or undefined when the kind is not list-indexed. */
|
|
256
|
+
declarationOf(kind) {
|
|
257
|
+
return this.byKind.get(kind);
|
|
258
|
+
}
|
|
259
|
+
/** Every declaration, in registration order. */
|
|
260
|
+
declarations() {
|
|
261
|
+
return [...this.byKind.values()];
|
|
262
|
+
}
|
|
263
|
+
/** A decoded row's facts when its kind is list-indexed; undefined otherwise. */
|
|
264
|
+
factsOf(kind, resource) {
|
|
265
|
+
const declaration = this.byKind.get(kind);
|
|
266
|
+
return declaration === undefined
|
|
267
|
+
? undefined
|
|
268
|
+
: listIndexFactsOf(declaration, resource);
|
|
269
|
+
}
|
|
270
|
+
/** Throws unless this exact declaration was registered. */
|
|
271
|
+
require(declaration) {
|
|
272
|
+
if (this.byKind.get(declaration.kind) !== declaration) {
|
|
273
|
+
throw new Error(`list index for ${apiResourceKindName(declaration.kind)} is not registered with this store`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=list-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-index.js","sourceRoot":"","sources":["../../src/store/list-index.ts"],"names":[],"mappings":"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"}
|
package/dist/store/logger.d.ts
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
* compatible with boot/logger.ts, declared here so the store layer never
|
|
4
4
|
* imports upward from boot/. Lived inline in sqlite/store.ts through
|
|
5
5
|
* Phase 1; promoted when the Postgres driver became the second consumer.
|
|
6
|
+
* `info` carries what an operator reads at boot (the list index's
|
|
7
|
+
* reconciliation count).
|
|
6
8
|
*/
|
|
7
9
|
export interface StoreLogger {
|
|
8
10
|
debug(message: string, fields?: Record<string, unknown>): void;
|
|
11
|
+
info(message: string, fields?: Record<string, unknown>): void;
|
|
9
12
|
warn(message: string, fields?: Record<string, unknown>): void;
|
|
10
13
|
}
|
|
11
14
|
/** Default for tests and tools that want a silent store. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/store/logger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/store/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC/D;AAED,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB,EAAE,WAI/B,CAAC"}
|
package/dist/store/logger.js
CHANGED
package/dist/store/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/store/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/store/logger.ts"],"names":[],"mappings":"AAcA,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAgB;IAC5C,KAAK,KAAI,CAAC;IACV,IAAI,KAAI,CAAC;IACT,IAAI,KAAI,CAAC;CACV,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Versioned schema migrations for the Postgres driver — an INDEPENDENT
|
|
3
3
|
* chain starting at its own v1 (DD-010 §3). It deliberately does NOT
|
|
4
|
-
* mirror sqlite's
|
|
4
|
+
* mirror sqlite's chain: that chain's value is Go-DDL fidelity for adopted
|
|
5
5
|
* laptop databases, a concern Postgres cannot have (no Postgres database
|
|
6
6
|
* predates this driver). Same runner discipline as sqlite/migrations.ts —
|
|
7
7
|
* deliberate, versioned, each step in its own transaction, `schema_version`
|
|
@@ -44,8 +44,10 @@ export declare const SCHEMA_VERSION_3 = 3;
|
|
|
44
44
|
export declare const SCHEMA_VERSION_4 = 4;
|
|
45
45
|
/** v5: every row holding the retired public visibility level moved to org. */
|
|
46
46
|
export declare const SCHEMA_VERSION_5 = 5;
|
|
47
|
+
/** v6: the list index's columns, key table and indexes (DDL only). */
|
|
48
|
+
export declare const SCHEMA_VERSION_6 = 6;
|
|
47
49
|
/** Target version for new databases. */
|
|
48
|
-
export declare const CURRENT_SCHEMA_VERSION =
|
|
50
|
+
export declare const CURRENT_SCHEMA_VERSION = 6;
|
|
49
51
|
/**
|
|
50
52
|
* Advisory lock key for the migration chain. Arbitrary but stable 64-bit
|
|
51
53
|
* value, derived from ASCII "STGMR1" — collisions with other advisory-lock
|
|
@@ -54,11 +56,13 @@ export declare const CURRENT_SCHEMA_VERSION = 5;
|
|
|
54
56
|
*/
|
|
55
57
|
export declare const MIGRATION_LOCK_KEY = 91621438607921n;
|
|
56
58
|
/**
|
|
57
|
-
* Applies
|
|
58
|
-
*
|
|
59
|
-
*
|
|
59
|
+
* Applies every pending migration up to `targetVersion` in order — all of
|
|
60
|
+
* them unless a test builds the database a given step starts from —
|
|
61
|
+
* serialized across instances by the advisory lock. Runs on a dedicated
|
|
62
|
+
* client (locks are session-scoped; a pool query could release on a
|
|
63
|
+
* different session).
|
|
60
64
|
*/
|
|
61
|
-
export declare function runMigrations(client: PoolClient): Promise<void>;
|
|
65
|
+
export declare function runMigrations(client: PoolClient, targetVersion?: number): Promise<void>;
|
|
62
66
|
/** Current schema version; 0 when none has been recorded yet. */
|
|
63
67
|
export declare function getSchemaVersion(client: PoolClient): Promise<number>;
|
|
64
68
|
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/store/postgres/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAOrC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,IAAmB,CAAC;AAEvD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/store/postgres/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAOrC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,wCAAwC;AACxC,eAAO,MAAM,sBAAsB,IAAmB,CAAC;AAEvD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,UAAU,EAClB,aAAa,GAAE,MAA+B,GAC7C,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,iEAAiE;AACjE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAK1E"}
|
|
@@ -6,8 +6,10 @@ export const SCHEMA_VERSION_3 = 3;
|
|
|
6
6
|
export const SCHEMA_VERSION_4 = 4;
|
|
7
7
|
/** v5: every row holding the retired public visibility level moved to org. */
|
|
8
8
|
export const SCHEMA_VERSION_5 = 5;
|
|
9
|
+
/** v6: the list index's columns, key table and indexes (DDL only). */
|
|
10
|
+
export const SCHEMA_VERSION_6 = 6;
|
|
9
11
|
/** Target version for new databases. */
|
|
10
|
-
export const CURRENT_SCHEMA_VERSION =
|
|
12
|
+
export const CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_6;
|
|
11
13
|
/**
|
|
12
14
|
* Advisory lock key for the migration chain. Arbitrary but stable 64-bit
|
|
13
15
|
* value, derived from ASCII "STGMR1" — collisions with other advisory-lock
|
|
@@ -16,11 +18,13 @@ export const CURRENT_SCHEMA_VERSION = SCHEMA_VERSION_5;
|
|
|
16
18
|
*/
|
|
17
19
|
export const MIGRATION_LOCK_KEY = 0x5354474d5231n;
|
|
18
20
|
/**
|
|
19
|
-
* Applies
|
|
20
|
-
*
|
|
21
|
-
*
|
|
21
|
+
* Applies every pending migration up to `targetVersion` in order — all of
|
|
22
|
+
* them unless a test builds the database a given step starts from —
|
|
23
|
+
* serialized across instances by the advisory lock. Runs on a dedicated
|
|
24
|
+
* client (locks are session-scoped; a pool query could release on a
|
|
25
|
+
* different session).
|
|
22
26
|
*/
|
|
23
|
-
export async function runMigrations(client) {
|
|
27
|
+
export async function runMigrations(client, targetVersion = CURRENT_SCHEMA_VERSION) {
|
|
24
28
|
await client.query("SELECT pg_advisory_lock($1)", [MIGRATION_LOCK_KEY]);
|
|
25
29
|
try {
|
|
26
30
|
await client.query(`
|
|
@@ -36,9 +40,10 @@ export async function runMigrations(client) {
|
|
|
36
40
|
[SCHEMA_VERSION_3, migrateToV3],
|
|
37
41
|
[SCHEMA_VERSION_4, migrateToV4],
|
|
38
42
|
[SCHEMA_VERSION_5, migrateToV5],
|
|
43
|
+
[SCHEMA_VERSION_6, migrateToV6],
|
|
39
44
|
];
|
|
40
45
|
for (const [version, migrate] of chain) {
|
|
41
|
-
if (currentVersion < version) {
|
|
46
|
+
if (currentVersion < version && version <= targetVersion) {
|
|
42
47
|
await applyInTransaction(client, version, migrate);
|
|
43
48
|
}
|
|
44
49
|
}
|
|
@@ -291,4 +296,57 @@ async function migrateToV5(client) {
|
|
|
291
296
|
}
|
|
292
297
|
}
|
|
293
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* v6: the list index (../list-index.ts) — schema only. Every existing row
|
|
301
|
+
* arrives with its stamp NULL, which makes it unproven, so the store's
|
|
302
|
+
* reconciliation at open derives its facts with the code that runs and
|
|
303
|
+
* reads stay exact until it has; a migration that decoded rows here would
|
|
304
|
+
* freeze today's declarations into the chain (the v5 step freezes its
|
|
305
|
+
* kind table for the same reason, public-visibility-retired.ts).
|
|
306
|
+
*
|
|
307
|
+
* - `list_org` and `list_created_at` are the order's inputs, byte-collated
|
|
308
|
+
* (`COLLATE "C"`) so the database sorts them the way list-index.ts
|
|
309
|
+
* compares them when it merges unproven rows in; `id` is compared under
|
|
310
|
+
* the same collation in the index expressions and the queries.
|
|
311
|
+
* - `list_index_revision` is the declaration revision the facts were
|
|
312
|
+
* derived under; `list_indexed_at` is the `updated_at` they were derived
|
|
313
|
+
* from. A writer that does not know these columns leaves them behind as
|
|
314
|
+
* it bumps `updated_at`, which is exactly what marks its row unproven.
|
|
315
|
+
* - `resource_list_keys` holds one row per (resource, key) with the
|
|
316
|
+
* creation instant copied in, so a parent's rows are one range of one
|
|
317
|
+
* index. It carries no foreign key: every indexed read joins
|
|
318
|
+
* `resources`, so a key row whose resource is gone matches nothing.
|
|
319
|
+
* - The partial index holds only unproven rows (none in steady state), so
|
|
320
|
+
* finding them is never a scan of the kind.
|
|
321
|
+
*/
|
|
322
|
+
async function migrateToV6(client) {
|
|
323
|
+
await client.query(`
|
|
324
|
+
ALTER TABLE resources
|
|
325
|
+
ADD COLUMN list_org TEXT COLLATE "C",
|
|
326
|
+
ADD COLUMN list_created_at TEXT COLLATE "C",
|
|
327
|
+
ADD COLUMN list_index_revision INTEGER,
|
|
328
|
+
ADD COLUMN list_indexed_at timestamptz;
|
|
329
|
+
|
|
330
|
+
CREATE INDEX idx_resources_list_org
|
|
331
|
+
ON resources (kind, list_org, list_created_at, (id COLLATE "C"));
|
|
332
|
+
CREATE INDEX idx_resources_list_created
|
|
333
|
+
ON resources (kind, list_created_at, (id COLLATE "C"));
|
|
334
|
+
CREATE INDEX idx_resources_list_revision
|
|
335
|
+
ON resources (kind, list_index_revision);
|
|
336
|
+
CREATE INDEX idx_resources_list_unproven
|
|
337
|
+
ON resources (kind, id) WHERE list_indexed_at IS DISTINCT FROM updated_at;
|
|
338
|
+
|
|
339
|
+
CREATE TABLE resource_list_keys (
|
|
340
|
+
kind TEXT NOT NULL,
|
|
341
|
+
id TEXT NOT NULL,
|
|
342
|
+
key TEXT NOT NULL,
|
|
343
|
+
value TEXT NOT NULL,
|
|
344
|
+
created_at TEXT COLLATE "C" NOT NULL,
|
|
345
|
+
PRIMARY KEY (kind, id, key)
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
CREATE INDEX idx_resource_list_keys_lookup
|
|
349
|
+
ON resource_list_keys (kind, key, value, created_at, (id COLLATE "C"));
|
|
350
|
+
`);
|
|
351
|
+
}
|
|
294
352
|
//# sourceMappingURL=migrations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/store/postgres/migrations.ts"],"names":[],"mappings":"AAwCA,OAAO,EACL,8BAA8B,EAC9B,kBAAkB,GACnB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,wDAAwD;AACxD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,wCAAwC;AACxC,MAAM,CAAC,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/store/postgres/migrations.ts"],"names":[],"mappings":"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"}
|