@spine-event-engine/storage-datastore 2.0.0-snapshot.10
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/LICENSE +201 -0
- package/README.md +262 -0
- package/REFERENCE.md +147 -0
- package/dist/datastore/column-mapping.d.ts +28 -0
- package/dist/datastore/column-mapping.d.ts.map +1 -0
- package/dist/datastore/column-mapping.js +141 -0
- package/dist/datastore/column-mapping.js.map +1 -0
- package/dist/datastore/delivery-cleanup.d.ts +31 -0
- package/dist/datastore/delivery-cleanup.d.ts.map +1 -0
- package/dist/datastore/delivery-cleanup.js +111 -0
- package/dist/datastore/delivery-cleanup.js.map +1 -0
- package/dist/datastore/entity-history.d.ts +82 -0
- package/dist/datastore/entity-history.d.ts.map +1 -0
- package/dist/datastore/entity-history.js +541 -0
- package/dist/datastore/entity-history.js.map +1 -0
- package/dist/datastore/id-column.d.ts +34 -0
- package/dist/datastore/id-column.d.ts.map +1 -0
- package/dist/datastore/id-column.js +103 -0
- package/dist/datastore/id-column.js.map +1 -0
- package/dist/datastore/namespace.d.ts +81 -0
- package/dist/datastore/namespace.d.ts.map +1 -0
- package/dist/datastore/namespace.js +123 -0
- package/dist/datastore/namespace.js.map +1 -0
- package/dist/datastore/record-storage.d.ts +223 -0
- package/dist/datastore/record-storage.d.ts.map +1 -0
- package/dist/datastore/record-storage.js +855 -0
- package/dist/datastore/record-storage.js.map +1 -0
- package/dist/datastore/storage-factory.d.ts +200 -0
- package/dist/datastore/storage-factory.d.ts.map +1 -0
- package/dist/datastore/storage-factory.js +224 -0
- package/dist/datastore/storage-factory.js.map +1 -0
- package/dist/datastore/tenant-catalog.d.ts +50 -0
- package/dist/datastore/tenant-catalog.d.ts.map +1 -0
- package/dist/datastore/tenant-catalog.js +154 -0
- package/dist/datastore/tenant-catalog.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/index.yaml +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, CodeMatters. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
5
|
+
* in compliance with the License. You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
10
|
+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
11
|
+
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
|
+
* the License.
|
|
13
|
+
*/
|
|
14
|
+
import { StringifierRegistry } from "@spine-event-engine/core";
|
|
15
|
+
/**
|
|
16
|
+
* Converts a declared record ID to and from a Spine JVM Datastore key name.
|
|
17
|
+
*/
|
|
18
|
+
export class DatastoreIdColumn {
|
|
19
|
+
type;
|
|
20
|
+
#stringifiers;
|
|
21
|
+
/**
|
|
22
|
+
* Creates the ID conversion.
|
|
23
|
+
*
|
|
24
|
+
* @param type The generated message schema or supported primitive ID kind.
|
|
25
|
+
* @param stringifiers The schema-bound message stringifiers.
|
|
26
|
+
*/
|
|
27
|
+
constructor(type, stringifiers = new StringifierRegistry()) {
|
|
28
|
+
this.type = type;
|
|
29
|
+
this.#stringifiers = new StringifierRegistry(stringifiers);
|
|
30
|
+
DatastoreIds.validateType(type);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Converts a logical ID to a Datastore key name.
|
|
34
|
+
*
|
|
35
|
+
* @param id The logical record identifier.
|
|
36
|
+
* @returns The JVM-compatible key name.
|
|
37
|
+
*/
|
|
38
|
+
value(id) {
|
|
39
|
+
const value = typeof this.type === "string"
|
|
40
|
+
? DatastoreIds.primitive(this.type, id)
|
|
41
|
+
: this.#stringifiers.forMessage(this.type).toString(id);
|
|
42
|
+
return DatastoreIds.keyName(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Restores a logical ID from a Datastore key name.
|
|
46
|
+
*
|
|
47
|
+
* @param value The Datastore key name.
|
|
48
|
+
* @returns The restored record identifier.
|
|
49
|
+
*/
|
|
50
|
+
read(value) {
|
|
51
|
+
DatastoreIds.keyName(value);
|
|
52
|
+
if (typeof this.type !== "string")
|
|
53
|
+
return this.#stringifiers.forMessage(this.type).fromString(value);
|
|
54
|
+
switch (this.type) {
|
|
55
|
+
case "string":
|
|
56
|
+
return value;
|
|
57
|
+
case "int32": {
|
|
58
|
+
const number = Number(value);
|
|
59
|
+
DatastoreIds.primitive("int32", number);
|
|
60
|
+
return number;
|
|
61
|
+
}
|
|
62
|
+
case "int64": {
|
|
63
|
+
const integer = BigInt(value);
|
|
64
|
+
DatastoreIds.primitive("int64", integer);
|
|
65
|
+
return integer;
|
|
66
|
+
}
|
|
67
|
+
default:
|
|
68
|
+
throw new Error(`Datastore storage does not support primitive ID kind "${this.type}".`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const DatastoreIds = Object.freeze({
|
|
73
|
+
validateType(type) {
|
|
74
|
+
if (typeof type !== "string")
|
|
75
|
+
return;
|
|
76
|
+
if (!["string", "int32", "int64"].includes(type))
|
|
77
|
+
throw new Error(`Datastore storage does not support primitive ID kind "${type}".`);
|
|
78
|
+
},
|
|
79
|
+
primitive(type, value) {
|
|
80
|
+
if (type === "string" && typeof value === "string")
|
|
81
|
+
return value;
|
|
82
|
+
if (type === "int32" &&
|
|
83
|
+
typeof value === "number" &&
|
|
84
|
+
Number.isInteger(value) &&
|
|
85
|
+
value >= -2_147_483_648 &&
|
|
86
|
+
value <= 2_147_483_647)
|
|
87
|
+
return String(value);
|
|
88
|
+
if (type === "int64" &&
|
|
89
|
+
typeof value === "bigint" &&
|
|
90
|
+
value >= -(1n << 63n) &&
|
|
91
|
+
value <= (1n << 63n) - 1n)
|
|
92
|
+
return value.toString();
|
|
93
|
+
throw new Error(`Datastore ${type} identifier is invalid.`);
|
|
94
|
+
},
|
|
95
|
+
keyName(value) {
|
|
96
|
+
if (value.length === 0)
|
|
97
|
+
throw new Error("Datastore storage identifier must be non-empty.");
|
|
98
|
+
if (Buffer.byteLength(value, "utf8") > 1_500)
|
|
99
|
+
throw new Error("Datastore record key exceeds the 1,500-byte provider limit.");
|
|
100
|
+
return value;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=id-column.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-column.js","sourceRoot":"","sources":["../../src/datastore/id-column.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type TenantId } from "@spine-event-engine/proto";
|
|
2
|
+
/**
|
|
3
|
+
* Converts complete tenant identifiers to and from Datastore namespaces.
|
|
4
|
+
*
|
|
5
|
+
* A converter must return a non-empty namespace and be injective over every
|
|
6
|
+
* admitted tenant. Converting in either direction and back must restore the
|
|
7
|
+
* exact complete tenant or namespace. Return `undefined` only for native
|
|
8
|
+
* namespaces that the converter does not own.
|
|
9
|
+
*/
|
|
10
|
+
export interface NamespaceConverter {
|
|
11
|
+
/**
|
|
12
|
+
* Converts an owned namespace to a complete tenant identifier.
|
|
13
|
+
*
|
|
14
|
+
* @param namespace The native Datastore namespace.
|
|
15
|
+
* @returns The tenant, or `undefined` when this converter does not own the namespace.
|
|
16
|
+
*/
|
|
17
|
+
fromNamespace(namespace: string): TenantId | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Converts a complete tenant identifier to its native namespace.
|
|
20
|
+
*
|
|
21
|
+
* @param tenantId The complete tenant identifier.
|
|
22
|
+
* @returns The native Datastore namespace.
|
|
23
|
+
*/
|
|
24
|
+
toNamespace(tenantId: TenantId): string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Safe Spine JVM-compatible `D` and `V` Datastore namespace conversion.
|
|
28
|
+
*/
|
|
29
|
+
export declare class DefaultNamespaceConverter implements NamespaceConverter {
|
|
30
|
+
/**
|
|
31
|
+
* Restores a tenant from an owned prefixed namespace.
|
|
32
|
+
*
|
|
33
|
+
* @param namespace The native Datastore namespace.
|
|
34
|
+
* @returns The restored tenant, or `undefined` for another namespace.
|
|
35
|
+
*/
|
|
36
|
+
fromNamespace(namespace: string): TenantId | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Converts a complete tenant to the Spine JVM-prefixed namespace.
|
|
39
|
+
*
|
|
40
|
+
* The Spine JVM email conversion replaces `@` with `-at-`. That mapping is
|
|
41
|
+
* not reversible and can assign distinct tenants to the same namespace, so
|
|
42
|
+
* this safe default rejects email tenants. Applications that use email
|
|
43
|
+
* tenant IDs must install the same injective custom converter in both
|
|
44
|
+
* runtimes.
|
|
45
|
+
*
|
|
46
|
+
* @param tenantId The complete tenant identifier.
|
|
47
|
+
* @returns The native Datastore namespace.
|
|
48
|
+
*/
|
|
49
|
+
toNamespace(tenantId: TenantId): string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Validates reversible tenant-to-namespace assignments.
|
|
53
|
+
*
|
|
54
|
+
* The same instance serves catalog admission and storage creation. A mapping
|
|
55
|
+
* is accepted only when applying the converter in the opposite direction
|
|
56
|
+
* restores the exact complete tenant or namespace.
|
|
57
|
+
*/
|
|
58
|
+
export declare class NamespaceAssignments implements NamespaceConverter {
|
|
59
|
+
private readonly converter;
|
|
60
|
+
/**
|
|
61
|
+
* Creates an assignment validator around an application converter.
|
|
62
|
+
*
|
|
63
|
+
* @param converter The converter whose mappings are validated.
|
|
64
|
+
*/
|
|
65
|
+
constructor(converter: NamespaceConverter);
|
|
66
|
+
/**
|
|
67
|
+
* Restores and validates an owned namespace.
|
|
68
|
+
*
|
|
69
|
+
* @param namespace The native namespace.
|
|
70
|
+
* @returns The restored tenant, or `undefined` when not owned.
|
|
71
|
+
*/
|
|
72
|
+
fromNamespace(namespace: string): TenantId | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Converts and validates a complete tenant.
|
|
75
|
+
*
|
|
76
|
+
* @param tenantId The complete tenant identifier.
|
|
77
|
+
* @returns Its unique, reversible native namespace.
|
|
78
|
+
*/
|
|
79
|
+
toNamespace(tenantId: TenantId): string;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=namespace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../src/datastore/namespace.ts"],"names":[],"mappings":"AAeA,OAAO,EAAwC,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAGhG;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IAGjC;;;;;OAKG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAEvD;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC;CACzC;AAED;;GAEG;AACH,qBAAa,yBAA0B,YAAW,kBAAkB;IAGlE;;;;;OAKG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAiBtD;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM;CAexC;AAED;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAQjD,OAAO,CAAC,QAAQ,CAAC,SAAS;IALtC;;;;OAIG;gBAC0B,SAAS,EAAE,kBAAkB;IAE1D;;;;;OAKG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAWtD;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM;CAUxC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, CodeMatters. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
5
|
+
* in compliance with the License. You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
10
|
+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
11
|
+
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
|
+
* the License.
|
|
13
|
+
*/
|
|
14
|
+
import { create } from "@bufbuild/protobuf";
|
|
15
|
+
import { InternetDomainSchema, TenantIdSchema } from "@spine-event-engine/proto";
|
|
16
|
+
import { TenantBoundary } from "@spine-event-engine/storage/provider";
|
|
17
|
+
/**
|
|
18
|
+
* Safe Spine JVM-compatible `D` and `V` Datastore namespace conversion.
|
|
19
|
+
*/
|
|
20
|
+
export class DefaultNamespaceConverter {
|
|
21
|
+
// prettier-ignore
|
|
22
|
+
/**
|
|
23
|
+
* Restores a tenant from an owned prefixed namespace.
|
|
24
|
+
*
|
|
25
|
+
* @param namespace The native Datastore namespace.
|
|
26
|
+
* @returns The restored tenant, or `undefined` for another namespace.
|
|
27
|
+
*/
|
|
28
|
+
fromNamespace(namespace) {
|
|
29
|
+
if (namespace.length < 2)
|
|
30
|
+
return undefined;
|
|
31
|
+
const value = namespace.slice(1);
|
|
32
|
+
switch (namespace[0]) {
|
|
33
|
+
case "D":
|
|
34
|
+
return create(TenantIdSchema, {
|
|
35
|
+
kind: { case: "domain", value: create(InternetDomainSchema, { value }) },
|
|
36
|
+
});
|
|
37
|
+
case "E":
|
|
38
|
+
return undefined;
|
|
39
|
+
case "V":
|
|
40
|
+
return create(TenantIdSchema, { kind: { case: "value", value } });
|
|
41
|
+
default:
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Converts a complete tenant to the Spine JVM-prefixed namespace.
|
|
47
|
+
*
|
|
48
|
+
* The Spine JVM email conversion replaces `@` with `-at-`. That mapping is
|
|
49
|
+
* not reversible and can assign distinct tenants to the same namespace, so
|
|
50
|
+
* this safe default rejects email tenants. Applications that use email
|
|
51
|
+
* tenant IDs must install the same injective custom converter in both
|
|
52
|
+
* runtimes.
|
|
53
|
+
*
|
|
54
|
+
* @param tenantId The complete tenant identifier.
|
|
55
|
+
* @returns The native Datastore namespace.
|
|
56
|
+
*/
|
|
57
|
+
toNamespace(tenantId) {
|
|
58
|
+
TenantBoundary.from(tenantId);
|
|
59
|
+
const kind = tenantId.kind;
|
|
60
|
+
if (kind.case === "email")
|
|
61
|
+
throw new Error("The default email namespace mapping is unsafe; install a reversible custom namespace converter.");
|
|
62
|
+
const namespace = kind.case === "domain"
|
|
63
|
+
? `D${kind.value.value}`
|
|
64
|
+
: kind.case === "value"
|
|
65
|
+
? `V${kind.value}`
|
|
66
|
+
: "";
|
|
67
|
+
return namespace;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validates reversible tenant-to-namespace assignments.
|
|
72
|
+
*
|
|
73
|
+
* The same instance serves catalog admission and storage creation. A mapping
|
|
74
|
+
* is accepted only when applying the converter in the opposite direction
|
|
75
|
+
* restores the exact complete tenant or namespace.
|
|
76
|
+
*/
|
|
77
|
+
export class NamespaceAssignments {
|
|
78
|
+
converter;
|
|
79
|
+
// prettier-ignore
|
|
80
|
+
/**
|
|
81
|
+
* Creates an assignment validator around an application converter.
|
|
82
|
+
*
|
|
83
|
+
* @param converter The converter whose mappings are validated.
|
|
84
|
+
*/
|
|
85
|
+
constructor(converter) {
|
|
86
|
+
this.converter = converter;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Restores and validates an owned namespace.
|
|
90
|
+
*
|
|
91
|
+
* @param namespace The native namespace.
|
|
92
|
+
* @returns The restored tenant, or `undefined` when not owned.
|
|
93
|
+
*/
|
|
94
|
+
fromNamespace(namespace) {
|
|
95
|
+
if (namespace.length === 0)
|
|
96
|
+
return undefined;
|
|
97
|
+
const tenantId = this.converter.fromNamespace(namespace);
|
|
98
|
+
if (tenantId === undefined)
|
|
99
|
+
return undefined;
|
|
100
|
+
TenantBoundary.from(tenantId);
|
|
101
|
+
const roundTrip = this.converter.toNamespace(tenantId);
|
|
102
|
+
if (roundTrip !== namespace)
|
|
103
|
+
throw new Error("Datastore namespace conversion must round trip exactly.");
|
|
104
|
+
return tenantId;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Converts and validates a complete tenant.
|
|
108
|
+
*
|
|
109
|
+
* @param tenantId The complete tenant identifier.
|
|
110
|
+
* @returns Its unique, reversible native namespace.
|
|
111
|
+
*/
|
|
112
|
+
toNamespace(tenantId) {
|
|
113
|
+
const boundary = TenantBoundary.from(tenantId);
|
|
114
|
+
const namespace = this.converter.toNamespace(tenantId);
|
|
115
|
+
if (namespace.trim().length === 0)
|
|
116
|
+
throw new Error("Datastore multitenancy requires a non-empty native namespace.");
|
|
117
|
+
const restored = this.converter.fromNamespace(namespace);
|
|
118
|
+
if (restored === undefined || TenantBoundary.from(restored).key !== boundary.key)
|
|
119
|
+
throw new Error("Datastore namespace conversion must round trip exactly.");
|
|
120
|
+
return namespace;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=namespace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../src/datastore/namespace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { type Message } from "@bufbuild/protobuf";
|
|
2
|
+
import { Datastore } from "@google-cloud/datastore";
|
|
3
|
+
import { StringifierRegistry } from "@spine-event-engine/core";
|
|
4
|
+
import { RecordStorage, type NormalizedQueryPlan, type RecordEntry, type RecordQuery, type RecordSpec, type StorageContext, type StorageGroup, type StorageQueryCapabilities } from "@spine-event-engine/storage";
|
|
5
|
+
import { type NamespaceConverter } from "./namespace.js";
|
|
6
|
+
/**
|
|
7
|
+
* Describes one provider-side Datastore range filter.
|
|
8
|
+
*
|
|
9
|
+
* This is deliberately package-private adapter machinery. It is used by the
|
|
10
|
+
* generated Entity-history implementation to keep large histories on the
|
|
11
|
+
* provider rather than materializing them in Node.js.
|
|
12
|
+
*/
|
|
13
|
+
export interface DatastoreRangeFilter {
|
|
14
|
+
/**
|
|
15
|
+
* Names the Datastore property compared by this filter.
|
|
16
|
+
*/
|
|
17
|
+
readonly property: string;
|
|
18
|
+
/**
|
|
19
|
+
* Selects the comparison applied by Datastore.
|
|
20
|
+
*/
|
|
21
|
+
readonly operator: "=" | "<" | "<=" | ">" | ">=";
|
|
22
|
+
/**
|
|
23
|
+
* Provides the value on the right side of the comparison.
|
|
24
|
+
*/
|
|
25
|
+
readonly value: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Describes a bounded provider-side page over one Datastore record kind.
|
|
29
|
+
*/
|
|
30
|
+
export interface DatastorePageQuery {
|
|
31
|
+
/**
|
|
32
|
+
* Narrows the page with provider-side comparisons.
|
|
33
|
+
*/
|
|
34
|
+
readonly filters?: readonly DatastoreRangeFilter[];
|
|
35
|
+
/**
|
|
36
|
+
* Defines the stable provider-side ordering of the page.
|
|
37
|
+
*/
|
|
38
|
+
readonly order?: readonly {
|
|
39
|
+
readonly property: string;
|
|
40
|
+
readonly direction: "asc" | "desc";
|
|
41
|
+
}[];
|
|
42
|
+
/**
|
|
43
|
+
* Continues after the last row returned by the preceding provider page.
|
|
44
|
+
*/
|
|
45
|
+
readonly cursor?: DatastorePageCursor;
|
|
46
|
+
/**
|
|
47
|
+
* Limits the number of rows decoded for this page.
|
|
48
|
+
*/
|
|
49
|
+
readonly limit: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns one bounded Datastore page and its explicit keyset continuation.
|
|
53
|
+
*/
|
|
54
|
+
export interface DatastorePage<I, R extends Message> {
|
|
55
|
+
/**
|
|
56
|
+
* Contains the decoded records in provider order.
|
|
57
|
+
*/
|
|
58
|
+
readonly entries: readonly RecordEntry<I, R>[];
|
|
59
|
+
/**
|
|
60
|
+
* Continues the next request after this page.
|
|
61
|
+
*/
|
|
62
|
+
readonly cursor: DatastorePageCursor | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Tells whether Datastore reported another page.
|
|
65
|
+
*/
|
|
66
|
+
readonly hasMore: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Identifies the last provider row in a stable ordered page.
|
|
70
|
+
*/
|
|
71
|
+
export interface DatastorePageCursor {
|
|
72
|
+
/**
|
|
73
|
+
* Values for the requested provider ordering.
|
|
74
|
+
*/
|
|
75
|
+
readonly values: readonly unknown[];
|
|
76
|
+
/**
|
|
77
|
+
* Physical key used as the deterministic final tie-breaker.
|
|
78
|
+
*/
|
|
79
|
+
readonly key: unknown;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Provides one Datastore-backed storage handle for a record family.
|
|
83
|
+
*/
|
|
84
|
+
export declare class DatastoreRecordStorage<I, R extends Message> extends RecordStorage<I, R> {
|
|
85
|
+
#private;
|
|
86
|
+
readonly client: Datastore;
|
|
87
|
+
/**
|
|
88
|
+
* Declares atomic conditional mutations for compatible Datastore handles.
|
|
89
|
+
*/
|
|
90
|
+
readonly atomicCompareAndSet = true;
|
|
91
|
+
/**
|
|
92
|
+
* Creates a Datastore-backed record storage handle.
|
|
93
|
+
*
|
|
94
|
+
* @param context Storage tenancy and naming context.
|
|
95
|
+
* @param recordSpec Schema, identifier, and column materialization contract.
|
|
96
|
+
* @param client Injected Datastore client owned by the factory.
|
|
97
|
+
* @param maxClientSideScan Maximum candidate records to materialize locally.
|
|
98
|
+
* @param group The optional generated storage group.
|
|
99
|
+
* @param kind The optional physical Datastore kind override.
|
|
100
|
+
* @param namespaceConverter Converts complete tenants to native namespaces.
|
|
101
|
+
* @param stringifiers Converts message-valued IDs and declared columns.
|
|
102
|
+
*/
|
|
103
|
+
constructor(context: StorageContext, recordSpec: RecordSpec<I, R>, client: Datastore, maxClientSideScan: number, group?: StorageGroup, kind?: string, namespaceConverter?: NamespaceConverter, stringifiers?: StringifierRegistry);
|
|
104
|
+
/**
|
|
105
|
+
* Prepares one resolved physical row for an enclosing transaction.
|
|
106
|
+
*
|
|
107
|
+
* @param record The record to materialize.
|
|
108
|
+
* @returns The Datastore key and property map.
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
transactionEntity(record: R): {
|
|
112
|
+
readonly key: ReturnType<Datastore["key"]>;
|
|
113
|
+
readonly data: Record<string, unknown>;
|
|
114
|
+
readonly excludeFromIndexes: readonly string[];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Decodes one entity read by a provider-owned multi-record transaction.
|
|
118
|
+
*
|
|
119
|
+
* @param entity The raw Datastore entity returned inside that transaction.
|
|
120
|
+
* @returns The decoded record.
|
|
121
|
+
* @internal
|
|
122
|
+
*/
|
|
123
|
+
decodeTransactionEntity(entity: Record<string | symbol, unknown>): R;
|
|
124
|
+
/**
|
|
125
|
+
* Checks whether one transaction-read entity is the exact expected record.
|
|
126
|
+
*
|
|
127
|
+
* @param entity The raw Datastore entity returned inside that transaction.
|
|
128
|
+
* @param expected The expected record snapshot.
|
|
129
|
+
* @returns Whether the persisted payload exactly matches the snapshot.
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
132
|
+
matchesTransactionEntity(entity: Record<string | symbol, unknown>, expected: R): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Reads one bounded, fully provider-executed page.
|
|
135
|
+
*
|
|
136
|
+
* Entity history uses this internal seam for records that would otherwise
|
|
137
|
+
* exceed the public query materialization budget.
|
|
138
|
+
*
|
|
139
|
+
* @param request The provider filters, ordering, continuation, and row limit.
|
|
140
|
+
* @returns The decoded page and an explicit continuation when more rows remain.
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
143
|
+
queryProviderPage(request: DatastorePageQuery): Promise<DatastorePage<I, R>>;
|
|
144
|
+
/**
|
|
145
|
+
* Deletes a bounded group of provider entries.
|
|
146
|
+
*
|
|
147
|
+
* @param entries The entries selected by a preceding provider page.
|
|
148
|
+
* @returns Completes after the provider deletes the group.
|
|
149
|
+
* @internal
|
|
150
|
+
*/
|
|
151
|
+
deleteProviderEntries(entries: readonly RecordEntry<I, R>[]): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Deletes the record at one storage slot.
|
|
154
|
+
* @param id The storage slot identifier.
|
|
155
|
+
* @returns Whether a record was deleted.
|
|
156
|
+
*/
|
|
157
|
+
protected deleteRecord(id: I): Promise<boolean>;
|
|
158
|
+
/**
|
|
159
|
+
* Returns records matching a query.
|
|
160
|
+
* @param _query The record query.
|
|
161
|
+
* @returns The matching storage entries.
|
|
162
|
+
*/
|
|
163
|
+
protected queryRecordEntries(_query: RecordQuery<I>): Promise<readonly RecordEntry<I, R>[]>;
|
|
164
|
+
/**
|
|
165
|
+
* Returns the supported Datastore query capabilities.
|
|
166
|
+
* @returns The supported query capabilities.
|
|
167
|
+
*/
|
|
168
|
+
protected queryCapabilities(): StorageQueryCapabilities;
|
|
169
|
+
/**
|
|
170
|
+
* Returns candidate records for a normalized query plan.
|
|
171
|
+
* @param plan The normalized query plan.
|
|
172
|
+
* @returns The candidate storage entries.
|
|
173
|
+
*/
|
|
174
|
+
protected queryPlanRecordEntries(plan: NormalizedQueryPlan<I>): Promise<readonly RecordEntry<I, R>[]>;
|
|
175
|
+
/**
|
|
176
|
+
* Reads the record at one storage slot.
|
|
177
|
+
* @param id The storage slot identifier.
|
|
178
|
+
* @returns The stored record, if present.
|
|
179
|
+
*/
|
|
180
|
+
protected readRecord(id: I): Promise<R | undefined>;
|
|
181
|
+
/**
|
|
182
|
+
* Compares and conditionally replaces the record at one storage slot.
|
|
183
|
+
* @param id The storage slot identifier.
|
|
184
|
+
* @param expected The expected materialized record.
|
|
185
|
+
* @param next The replacement materialized record, if any.
|
|
186
|
+
* @returns Whether the conditional mutation was applied.
|
|
187
|
+
*/
|
|
188
|
+
protected compareAndSetRecord(id: I, expected: ReturnType<RecordSpec<I, R>["materialize"]> | undefined, next: ReturnType<RecordSpec<I, R>["materialize"]> | undefined): Promise<boolean>;
|
|
189
|
+
private attemptCompareAndSet;
|
|
190
|
+
/**
|
|
191
|
+
* Writes materialized records.
|
|
192
|
+
* @param records The materialized records to write.
|
|
193
|
+
* @returns Completes when the records are written.
|
|
194
|
+
*/
|
|
195
|
+
protected writeAllRecords(records: readonly ReturnType<RecordSpec<I, R>["materialize"]>[]): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* Writes one materialized record.
|
|
198
|
+
* @param record The materialized record to write.
|
|
199
|
+
* @returns Completes when the record is written.
|
|
200
|
+
*/
|
|
201
|
+
protected writeRecord(record: ReturnType<RecordSpec<I, R>["materialize"]>): Promise<void>;
|
|
202
|
+
private provider;
|
|
203
|
+
/**
|
|
204
|
+
* Creates a transaction scoped to this handle's selected namespace.
|
|
205
|
+
*
|
|
206
|
+
* @returns The namespace-scoped Datastore transaction.
|
|
207
|
+
* @internal
|
|
208
|
+
*/
|
|
209
|
+
transaction(): ReturnType<Datastore["transaction"]>;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Raised when a query would exceed the adapter's configured finite client-side scan budget.
|
|
213
|
+
*/
|
|
214
|
+
export declare class DatastoreQueryLimitError extends Error {
|
|
215
|
+
readonly maxClientSideScan: number;
|
|
216
|
+
/**
|
|
217
|
+
* Creates the scan-budget error.
|
|
218
|
+
*
|
|
219
|
+
* @param maxClientSideScan Configured maximum number of locally scanned candidates.
|
|
220
|
+
*/
|
|
221
|
+
constructor(maxClientSideScan: number);
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=record-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-storage.d.ts","sourceRoot":"","sources":["../../src/datastore/record-storage.ts"],"names":[],"mappings":"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"}
|