@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.
Files changed (42) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +262 -0
  3. package/REFERENCE.md +147 -0
  4. package/dist/datastore/column-mapping.d.ts +28 -0
  5. package/dist/datastore/column-mapping.d.ts.map +1 -0
  6. package/dist/datastore/column-mapping.js +141 -0
  7. package/dist/datastore/column-mapping.js.map +1 -0
  8. package/dist/datastore/delivery-cleanup.d.ts +31 -0
  9. package/dist/datastore/delivery-cleanup.d.ts.map +1 -0
  10. package/dist/datastore/delivery-cleanup.js +111 -0
  11. package/dist/datastore/delivery-cleanup.js.map +1 -0
  12. package/dist/datastore/entity-history.d.ts +82 -0
  13. package/dist/datastore/entity-history.d.ts.map +1 -0
  14. package/dist/datastore/entity-history.js +541 -0
  15. package/dist/datastore/entity-history.js.map +1 -0
  16. package/dist/datastore/id-column.d.ts +34 -0
  17. package/dist/datastore/id-column.d.ts.map +1 -0
  18. package/dist/datastore/id-column.js +103 -0
  19. package/dist/datastore/id-column.js.map +1 -0
  20. package/dist/datastore/namespace.d.ts +81 -0
  21. package/dist/datastore/namespace.d.ts.map +1 -0
  22. package/dist/datastore/namespace.js +123 -0
  23. package/dist/datastore/namespace.js.map +1 -0
  24. package/dist/datastore/record-storage.d.ts +223 -0
  25. package/dist/datastore/record-storage.d.ts.map +1 -0
  26. package/dist/datastore/record-storage.js +855 -0
  27. package/dist/datastore/record-storage.js.map +1 -0
  28. package/dist/datastore/storage-factory.d.ts +200 -0
  29. package/dist/datastore/storage-factory.d.ts.map +1 -0
  30. package/dist/datastore/storage-factory.js +224 -0
  31. package/dist/datastore/storage-factory.js.map +1 -0
  32. package/dist/datastore/tenant-catalog.d.ts +50 -0
  33. package/dist/datastore/tenant-catalog.d.ts.map +1 -0
  34. package/dist/datastore/tenant-catalog.js +154 -0
  35. package/dist/datastore/tenant-catalog.js.map +1 -0
  36. package/dist/index.d.ts +6 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +19 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/tsconfig.tsbuildinfo +1 -0
  41. package/index.yaml +1 -0
  42. package/package.json +40 -0
@@ -0,0 +1,141 @@
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 { ScalarType } from "@bufbuild/protobuf";
15
+ import { Datastore } from "@google-cloud/datastore";
16
+ import { StringifierRegistry } from "@spine-event-engine/core";
17
+ const timestampType = "google.protobuf.Timestamp";
18
+ const versionType = "spine.core.Version";
19
+ /**
20
+ * Converts typed Protobuf column values to Spine JVM Datastore values.
21
+ */
22
+ export class DatastoreColumnMapping {
23
+ #stringifiers;
24
+ /**
25
+ * Creates a JVM-compatible Datastore column mapping.
26
+ *
27
+ * @param stringifiers The schema-bound message stringifiers.
28
+ */
29
+ constructor(stringifiers = new StringifierRegistry()) {
30
+ this.#stringifiers = new StringifierRegistry(stringifiers);
31
+ }
32
+ /**
33
+ * Returns the conversion for one generated column type.
34
+ *
35
+ * @param type The generated Protobuf column type.
36
+ * @returns The JVM-compatible Datastore conversion.
37
+ */
38
+ of(type) {
39
+ switch (type.kind) {
40
+ case "scalar":
41
+ return DatastoreMappings.scalar(type.scalar);
42
+ case "enum":
43
+ return (value) => Datastore.int(String(value));
44
+ case "message":
45
+ if (type.message.typeName === timestampType)
46
+ return (value) => DatastoreMappings.timestamp(value);
47
+ if (type.message.typeName === versionType)
48
+ return (value) => Datastore.int(String(value.number));
49
+ return (value) => this.#stringifiers
50
+ .forMessage(type.message)
51
+ .toString(value);
52
+ }
53
+ }
54
+ /**
55
+ * Returns native Datastore null.
56
+ *
57
+ * @returns The null conversion.
58
+ */
59
+ ofNull() {
60
+ return (value) => value;
61
+ }
62
+ }
63
+ const DatastoreMappings = Object.freeze({
64
+ scalar(type) {
65
+ switch (type) {
66
+ case ScalarType.STRING:
67
+ case ScalarType.BOOL:
68
+ return (value) => value;
69
+ case ScalarType.INT32:
70
+ case ScalarType.SINT32:
71
+ case ScalarType.SFIXED32:
72
+ return (value) => Datastore.int(DatastoreMappings.signed(value, 32));
73
+ case ScalarType.UINT32:
74
+ case ScalarType.FIXED32:
75
+ return (value) => Datastore.int(DatastoreMappings.unsigned(value, 32));
76
+ case ScalarType.INT64:
77
+ case ScalarType.SINT64:
78
+ case ScalarType.SFIXED64:
79
+ return (value) => Datastore.int(DatastoreMappings.signed(value, 64));
80
+ case ScalarType.UINT64:
81
+ case ScalarType.FIXED64:
82
+ return (value) => Datastore.int(DatastoreMappings.unsigned(value, 64));
83
+ case ScalarType.FLOAT:
84
+ case ScalarType.DOUBLE:
85
+ return (value) => Datastore.double(value);
86
+ case ScalarType.BYTES:
87
+ return (value) => Buffer.from(value);
88
+ }
89
+ },
90
+ signed(value, bits) {
91
+ const integer = this.integer(value);
92
+ const limit = 1n << BigInt(bits - 1);
93
+ if (integer < -limit || integer >= limit)
94
+ throw new Error(`Datastore signed ${String(bits)}-bit column is outside its range.`);
95
+ return integer.toString();
96
+ },
97
+ unsigned(value, bits) {
98
+ const integer = this.integer(value);
99
+ if (integer < 0n || integer >= 1n << BigInt(bits))
100
+ throw new Error(`Datastore unsigned ${String(bits)}-bit column is outside its range.`);
101
+ if (integer > (1n << 63n) - 1n)
102
+ throw new Error("Datastore integer columns cannot exceed the signed 64-bit provider range.");
103
+ return integer.toString();
104
+ },
105
+ integer(value) {
106
+ if (typeof value === "bigint")
107
+ return value;
108
+ if (typeof value === "number" && Number.isSafeInteger(value))
109
+ return BigInt(value);
110
+ if (typeof value === "string" && /^-?(?:0|[1-9][0-9]*)$/u.test(value))
111
+ return BigInt(value);
112
+ throw new Error("Datastore integer column is invalid.");
113
+ },
114
+ timestamp(value) {
115
+ const timestamp = value;
116
+ if (typeof timestamp.seconds !== "bigint" ||
117
+ !Number.isInteger(timestamp.nanos) ||
118
+ timestamp.nanos < 0 ||
119
+ timestamp.nanos > 999_999_999)
120
+ throw new Error("Datastore timestamp column is invalid.");
121
+ return new DatastoreTimestamp(timestamp.seconds, timestamp.nanos);
122
+ },
123
+ });
124
+ class DatastoreTimestamp extends Date {
125
+ seconds;
126
+ nanos;
127
+ constructor(seconds, nanos) {
128
+ super(Number(seconds * 1000n));
129
+ this.seconds = seconds;
130
+ this.nanos = nanos;
131
+ if (!Number.isFinite(super.getTime()))
132
+ throw new Error("Datastore timestamp column is outside the supported range.");
133
+ }
134
+ getTime() {
135
+ return Number(this.seconds * 1000n);
136
+ }
137
+ getMilliseconds() {
138
+ return this.nanos / 1_000_000;
139
+ }
140
+ }
141
+ //# sourceMappingURL=column-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column-mapping.js","sourceRoot":"","sources":["../../src/datastore/column-mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAgB,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAO/D,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACxB,aAAa,CAAsB;IAE5C;;;;OAIG;IACH,YAAY,eAAoC,IAAI,mBAAmB,EAAE;QACvE,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,EAAE,CAAI,IAAyB;QAC7B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,QAAQ;gBACX,OAAO,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/C,KAAK,MAAM;gBACT,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACjD,KAAK,SAAS;gBACZ,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,aAAa;oBACzC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACvD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,WAAW;oBACvC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAE,KAAqC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzF,OAAO,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,CAAC,aAAa;qBACf,UAAU,CAAC,IAAI,CAAC,OAA8B,CAAC;qBAC/C,QAAQ,CAAC,KAAgB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,MAAM,CAAI,IAAgB;QACxB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,UAAU,CAAC,MAAM,CAAC;YACvB,KAAK,UAAU,CAAC,IAAI;gBAClB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;YAC1B,KAAK,UAAU,CAAC,KAAK,CAAC;YACtB,KAAK,UAAU,CAAC,MAAM,CAAC;YACvB,KAAK,UAAU,CAAC,QAAQ;gBACtB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;YACvE,KAAK,UAAU,CAAC,MAAM,CAAC;YACvB,KAAK,UAAU,CAAC,OAAO;gBACrB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;YACzE,KAAK,UAAU,CAAC,KAAK,CAAC;YACtB,KAAK,UAAU,CAAC,MAAM,CAAC;YACvB,KAAK,UAAU,CAAC,QAAQ;gBACtB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;YACvE,KAAK,UAAU,CAAC,MAAM,CAAC;YACvB,KAAK,UAAU,CAAC,OAAO;gBACrB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;YACzE,KAAK,UAAU,CAAC,KAAK,CAAC;YACtB,KAAK,UAAU,CAAC,MAAM;gBACpB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAe,CAAC,CAAC;YACtD,KAAK,UAAU,CAAC,KAAK;gBACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAmB,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAc,EAAE,IAAa;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,EAAE,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACrC,IAAI,OAAO,GAAG,CAAC,KAAK,IAAI,OAAO,IAAI,KAAK;YACtC,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,KAAc,EAAE,IAAa;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACzF,IAAI,OAAO,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC/F,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,KAAc;QACpB,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACnF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,SAAS,CAAC,KAAc;QACtB,MAAM,SAAS,GAAG,KAA6D,CAAC;QAChF,IACE,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;YACrC,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC;YAClC,SAAS,CAAC,KAAK,GAAG,CAAC;YACnB,SAAS,CAAC,KAAK,GAAG,WAAW;YAE7B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,OAAO,IAAI,kBAAkB,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,kBAAmB,SAAQ,IAAI;IAEhB;IACA;IAFnB,YACmB,OAAe,EACf,KAAa;QAE9B,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,KAAM,CAAC,CAAC,CAAC;QAHf,YAAO,GAAP,OAAO,CAAQ;QACf,UAAK,GAAL,KAAK,CAAQ;QAG9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAClF,CAAC;IAEQ,OAAO;QACd,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,KAAM,CAAC,CAAC;IACvC,CAAC;IAEQ,eAAe;QACtB,OAAO,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ import type { Message } from "@bufbuild/protobuf";
2
+ import { type DeliveryCleanupInput, type DeliveryCleanupStorage } from "@spine-event-engine/storage/provider";
3
+ import type { RecordSpec, StorageContext } from "@spine-event-engine/storage";
4
+ import { DatastoreRecordStorage } from "./record-storage.js";
5
+ /**
6
+ * Coordinates one fenced delivered Inbox deletion in Datastore.
7
+ */
8
+ export declare class DatastoreDeliveryCleanupStorage implements DeliveryCleanupStorage {
9
+ #private;
10
+ private readonly openStorage;
11
+ /**
12
+ * Creates a Datastore cleanup coordinator.
13
+ *
14
+ * @param openStorage Opens a record-storage handle for one record family.
15
+ */
16
+ constructor(openStorage: <I, R extends Message>(context: StorageContext, spec: RecordSpec<I, R>) => DatastoreRecordStorage<I, R>);
17
+ /**
18
+ * Removes an exact Inbox entity after validating its session entity in one transaction.
19
+ *
20
+ * @param input Describes the records and ownership predicate for deletion.
21
+ * @returns Whether the transaction deleted the exact Inbox entity.
22
+ */
23
+ remove<InboxId, InboxRecord extends Message, SessionId, SessionRecord extends Message>(input: DeliveryCleanupInput<InboxId, InboxRecord, SessionId, SessionRecord>): Promise<boolean>;
24
+ /**
25
+ * Closes this cleanup coordinator to further removal operations.
26
+ */
27
+ close(): void;
28
+ private static first;
29
+ private static active;
30
+ }
31
+ //# sourceMappingURL=delivery-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-cleanup.d.ts","sourceRoot":"","sources":["../../src/datastore/delivery-cleanup.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,qBAAa,+BAAgC,YAAW,sBAAsB;;IAS1E,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B;;;;OAIG;gBAEgB,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EACjD,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KACnB,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC;IAGnC;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,WAAW,SAAS,OAAO,EAAE,SAAS,EAAE,aAAa,SAAS,OAAO,EACzF,KAAK,EAAE,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,CAAC,GAC1E,OAAO,CAAC,OAAO,CAAC;IA8DnB;;OAEG;IACH,KAAK,IAAI,IAAI;IAGb,OAAO,CAAC,MAAM,CAAC,KAAK;IAQpB,OAAO,CAAC,MAAM,CAAC,MAAM;CAGtB"}
@@ -0,0 +1,111 @@
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 { cleanupOperationActive, } from "@spine-event-engine/storage/provider";
15
+ import { DatastoreRecordStorage } from "./record-storage.js";
16
+ /**
17
+ * Coordinates one fenced delivered Inbox deletion in Datastore.
18
+ */
19
+ export class DatastoreDeliveryCleanupStorage {
20
+ openStorage;
21
+ #open = true;
22
+ /**
23
+ * Creates a Datastore cleanup coordinator.
24
+ *
25
+ * @param openStorage Opens a record-storage handle for one record family.
26
+ */
27
+ constructor(openStorage) {
28
+ this.openStorage = openStorage;
29
+ }
30
+ /**
31
+ * Removes an exact Inbox entity after validating its session entity in one transaction.
32
+ *
33
+ * @param input Describes the records and ownership predicate for deletion.
34
+ * @returns Whether the transaction deleted the exact Inbox entity.
35
+ */
36
+ async remove(input) {
37
+ if (!this.#open)
38
+ throw new Error("Delivery cleanup storage is closed.");
39
+ if (!DatastoreDeliveryCleanupStorage.active(input))
40
+ return false;
41
+ const inbox = this.openStorage(input.context, input.inbox.spec);
42
+ const sessions = this.openStorage(input.context, input.session.spec);
43
+ const transaction = sessions.transaction();
44
+ try {
45
+ await transaction.run();
46
+ const sessionEntity = DatastoreDeliveryCleanupStorage.first(await transaction.get(sessions.transactionEntity(input.session.expected).key));
47
+ if (!DatastoreDeliveryCleanupStorage.active(input)) {
48
+ await transaction.rollback();
49
+ return false;
50
+ }
51
+ if (sessionEntity === undefined ||
52
+ !sessions.matchesTransactionEntity(sessionEntity, input.session.expected) ||
53
+ !input.session.isCurrent(sessions.decodeTransactionEntity(sessionEntity))) {
54
+ await transaction.rollback();
55
+ return false;
56
+ }
57
+ const expectedInbox = inbox.transactionEntity(input.inbox.expected);
58
+ const inboxEntity = DatastoreDeliveryCleanupStorage.first(await transaction.get(expectedInbox.key));
59
+ if (inboxEntity === undefined ||
60
+ !inbox.matchesTransactionEntity(inboxEntity, input.inbox.expected)) {
61
+ await transaction.rollback();
62
+ return false;
63
+ }
64
+ if (!input.session.isCurrent(sessions.decodeTransactionEntity(sessionEntity))) {
65
+ await transaction.rollback();
66
+ return false;
67
+ }
68
+ if (!DatastoreDeliveryCleanupStorage.active(input)) {
69
+ await transaction.rollback();
70
+ return false;
71
+ }
72
+ transaction.delete(expectedInbox.key);
73
+ if (!input.session.isCurrent(sessions.decodeTransactionEntity(sessionEntity))) {
74
+ await transaction.rollback();
75
+ return false;
76
+ }
77
+ if (!DatastoreDeliveryCleanupStorage.active(input)) {
78
+ await transaction.rollback();
79
+ return false;
80
+ }
81
+ await transaction.commit();
82
+ return true;
83
+ }
84
+ catch (error) {
85
+ await transaction.rollback().catch(() => undefined);
86
+ throw error;
87
+ }
88
+ finally {
89
+ inbox.close();
90
+ sessions.close();
91
+ }
92
+ }
93
+ /**
94
+ * Closes this cleanup coordinator to further removal operations.
95
+ */
96
+ close() {
97
+ this.#open = false;
98
+ }
99
+ static first(value) {
100
+ return Array.isArray(value) &&
101
+ value.length > 0 &&
102
+ typeof value[0] === "object" &&
103
+ value[0] !== null
104
+ ? value[0]
105
+ : undefined;
106
+ }
107
+ static active(input) {
108
+ return cleanupOperationActive(input.operation);
109
+ }
110
+ }
111
+ //# sourceMappingURL=delivery-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-cleanup.js","sourceRoot":"","sources":["../../src/datastore/delivery-cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACL,sBAAsB,GAIvB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,+BAA+B;IASvB;IARnB,KAAK,GAAG,IAAI,CAAC;IAEb;;;;OAIG;IACH,YACmB,WAGgB;QAHhB,gBAAW,GAAX,WAAW,CAGK;IAChC,CAAC;IAEJ;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CACV,KAA2E;QAE3E,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACxE,IAAI,CAAC,+BAA+B,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;YACxB,MAAM,aAAa,GAAG,+BAA+B,CAAC,KAAK,CACzD,MAAM,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAC9E,CAAC;YACF,IAAI,CAAC,+BAA+B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IACE,aAAa,KAAK,SAAS;gBAC3B,CAAC,QAAQ,CAAC,wBAAwB,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACzE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,EACzE,CAAC;gBACD,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,aAAa,GAAG,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpE,MAAM,WAAW,GAAG,+BAA+B,CAAC,KAAK,CACvD,MAAM,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CACzC,CAAC;YACF,IACE,WAAW,KAAK,SAAS;gBACzB,CAAC,KAAK,CAAC,wBAAwB,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAClE,CAAC;gBACD,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;gBAC9E,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC,+BAA+B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;gBAC9E,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC,+BAA+B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,WAAW,CAAC,MAAM,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACpD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IACO,MAAM,CAAC,KAAK,CAAC,KAAc;QACjC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACzB,KAAK,CAAC,MAAM,GAAG,CAAC;YAChB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;YAC5B,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;YACjB,CAAC,CAAE,KAAK,CAAC,CAAC,CAAsC;YAChD,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IACO,MAAM,CAAC,MAAM,CAAC,KAAgD;QACpE,OAAO,sBAAsB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,82 @@
1
+ import { type Message } from "@bufbuild/protobuf";
2
+ import { type EntityCommitInput, type EntityCommitResult, type EntityCommitStorage, type EntityEventHistoryPort, type EntityRecordStorage, type EntityStateHistoryPort, type EntityStorageInput } from "@spine-event-engine/storage/provider";
3
+ import { RecordSpec, type RecordStorage } from "@spine-event-engine/storage";
4
+ /**
5
+ * Opens one generated record family with its resolved Datastore layout.
6
+ *
7
+ * @param spec The generated record-family contract.
8
+ * @param group The optional generated storage group.
9
+ * @returns The opened record-storage handle.
10
+ */
11
+ export type OpenEntityRecords = <I, R extends Message>(spec: RecordSpec<I, R>, group?: import("@spine-event-engine/storage").StorageGroup) => RecordStorage<I, R>;
12
+ /**
13
+ * Groups Entity current and optional history record families.
14
+ */
15
+ export declare class DatastoreEntityStorage<I, S extends Message> {
16
+ #private;
17
+ /**
18
+ * Provides access to current Entity records.
19
+ */
20
+ readonly current: EntityRecordStorage<I>;
21
+ /**
22
+ * Provides access to retained Entity event history.
23
+ */
24
+ readonly events: EntityEventHistoryPort<I>;
25
+ /**
26
+ * Provides access to retained Entity state history.
27
+ */
28
+ readonly states: EntityStateHistoryPort<I, S>;
29
+ /**
30
+ * Creates storage handles for one Entity persistence contract.
31
+ *
32
+ * @param input The Entity persistence contract.
33
+ * @param openRecords The function that opens each generated record family.
34
+ */
35
+ constructor(input: EntityStorageInput<I, S>, openRecords: OpenEntityRecords);
36
+ /**
37
+ * Closes all record-storage handles owned by this Entity storage.
38
+ */
39
+ close(): void;
40
+ /**
41
+ * Returns whether this Entity storage remains open.
42
+ *
43
+ * @returns `true` when this storage accepts operations.
44
+ */
45
+ isOpen(): boolean;
46
+ }
47
+ /**
48
+ * Coordinates an Entity mutation through one Datastore transaction.
49
+ */
50
+ export declare class DatastoreEntityCommitStorage implements EntityCommitStorage {
51
+ #private;
52
+ private readonly input;
53
+ private readonly openRecords;
54
+ /**
55
+ * Creates transactional commit storage for one Entity persistence contract.
56
+ *
57
+ * @param input The Entity persistence contract served by this instance.
58
+ * @param openRecords The function that opens generated record families.
59
+ */
60
+ constructor(input: EntityStorageInput<unknown, Message>, openRecords: OpenEntityRecords);
61
+ /**
62
+ * Commits one Entity state transition and its generated history records.
63
+ *
64
+ * @param input The Entity mutation to commit.
65
+ * @returns The committed or conflicting outcome.
66
+ */
67
+ commit<I, S extends Message>(input: EntityCommitInput<I, S>): Promise<EntityCommitResult>;
68
+ private run;
69
+ private prepare;
70
+ private tryCommit;
71
+ private load;
72
+ private conflict;
73
+ private validateImmutable;
74
+ private apply;
75
+ private closeRecords;
76
+ /**
77
+ * Closes this commit storage to further commits.
78
+ */
79
+ close(): void;
80
+ private validate;
81
+ }
82
+ //# sourceMappingURL=entity-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-history.d.ts","sourceRoot":"","sources":["../../src/datastore/entity-history.ts"],"names":[],"mappings":"AAcA,OAAO,EAA+B,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAQ/E,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACxB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAe7E;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EACnD,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,KAAK,CAAC,EAAE,OAAO,6BAA6B,EAAE,YAAY,KACvD,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEzB;;GAEG;AACH,qBAAa,sBAAsB,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO;;IAGtD;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAEzC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAE3C;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAI9C;;;;;OAKG;gBACS,KAAK,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,iBAAiB;IAsB3E;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;;;OAIG;IACH,MAAM,IAAI,OAAO;CAGlB;AAED;;GAEG;AACH,qBAAa,4BAA6B,YAAW,mBAAmB;;IAUpE,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR9B;;;;;OAKG;gBAEgB,KAAK,EAAE,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,EAC3C,WAAW,EAAE,iBAAiB;IAGjD;;;;;OAKG;IACG,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;YA4BjF,GAAG;IAuBjB,OAAO,CAAC,OAAO;YAeD,SAAS;YAoBT,IAAI;YAgBJ,QAAQ;IAetB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,YAAY;IAYpB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,QAAQ;CAcjB"}