@spine-event-engine/storage-mysql 2.0.0-snapshot.24 → 2.0.0-snapshot.26

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 (51) hide show
  1. package/README.md +34 -26
  2. package/REFERENCE.md +47 -47
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/mysql/agent-history.d.ts +47 -8
  7. package/dist/mysql/agent-history.d.ts.map +1 -1
  8. package/dist/mysql/agent-history.js +85 -19
  9. package/dist/mysql/agent-history.js.map +1 -1
  10. package/dist/mysql/agent-transaction.d.ts +6 -0
  11. package/dist/mysql/agent-transaction.d.ts.map +1 -1
  12. package/dist/mysql/agent-transaction.js +15 -0
  13. package/dist/mysql/agent-transaction.js.map +1 -1
  14. package/dist/mysql/column-mapping.d.ts +1 -0
  15. package/dist/mysql/column-mapping.d.ts.map +1 -1
  16. package/dist/mysql/column-mapping.js +26 -3
  17. package/dist/mysql/column-mapping.js.map +1 -1
  18. package/dist/mysql/entity-history.d.ts +23 -6
  19. package/dist/mysql/entity-history.d.ts.map +1 -1
  20. package/dist/mysql/entity-history.js +210 -48
  21. package/dist/mysql/entity-history.js.map +1 -1
  22. package/dist/mysql/id-column.d.ts +7 -0
  23. package/dist/mysql/id-column.d.ts.map +1 -1
  24. package/dist/mysql/id-column.js +27 -3
  25. package/dist/mysql/id-column.js.map +1 -1
  26. package/dist/mysql/record-storage.d.ts +175 -34
  27. package/dist/mysql/record-storage.d.ts.map +1 -1
  28. package/dist/mysql/record-storage.js +317 -140
  29. package/dist/mysql/record-storage.js.map +1 -1
  30. package/dist/mysql/storage-factory.d.ts +284 -29
  31. package/dist/mysql/storage-factory.d.ts.map +1 -1
  32. package/dist/mysql/storage-factory.js +1226 -170
  33. package/dist/mysql/storage-factory.js.map +1 -1
  34. package/dist/mysql/table-resolver.d.ts +26 -1
  35. package/dist/mysql/table-resolver.d.ts.map +1 -1
  36. package/dist/mysql/table-resolver.js +69 -18
  37. package/dist/mysql/table-resolver.js.map +1 -1
  38. package/dist/mysql/table-spec.d.ts +0 -4
  39. package/dist/mysql/table-spec.d.ts.map +1 -1
  40. package/dist/mysql/table-spec.js +2 -34
  41. package/dist/mysql/table-spec.js.map +1 -1
  42. package/dist/mysql/testing.d.ts +8 -0
  43. package/dist/mysql/testing.d.ts.map +1 -1
  44. package/dist/mysql/testing.js +23 -2
  45. package/dist/mysql/testing.js.map +1 -1
  46. package/dist/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +5 -6
  48. package/dist/mysql/agent-execution.d.ts +0 -276
  49. package/dist/mysql/agent-execution.d.ts.map +0 -1
  50. package/dist/mysql/agent-execution.js +0 -630
  51. package/dist/mysql/agent-execution.js.map +0 -1
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # MySQL storage for Spine TS
2
2
 
3
+ See [storage layout and database preparation](https://github.com/SpineEventEngine/spine-ts/blob/master/docs/STORAGE_LAYOUT.md) for
4
+ physical structures, tenant placement, prerequisites, and customization.
5
+
3
6
  `@spine-event-engine/storage-mysql` stores Spine TS records in MySQL. It is a
4
7
  durable implementation of `@spine-event-engine/storage` and manages the mysql2
5
8
  connection pool and its private tables. PostgreSQL is not supported by this
@@ -11,8 +14,9 @@ record schemas, and a reachable MySQL database.
11
14
  For database requirements, query limits, lifecycle, and error details, see
12
15
  [REFERENCE documentation for agents](REFERENCE.md).
13
16
 
14
- For an application using Agents, this provider keeps the Agent's accepted
15
- work and recorded interactions across restarts. Use InnoDB for Agent repositories;
17
+ For an application using Agents, this provider retains typed admission receipts,
18
+ Entity state, and recorded interactions across restarts, without resuming an
19
+ interrupted handler. Use InnoDB for Agent repositories;
16
20
  see the [coding-agent reference](REFERENCE.md) for database requirements.
17
21
 
18
22
  ## 💡 Why use it?
@@ -38,9 +42,12 @@ The snapshot tag can change before a stable release.
38
42
 
39
43
  ## 🔌 Create and close a MySQL factory
40
44
 
41
- Provide a MySQL URL that includes a database name. Building the factory opens
42
- its pool only; each record family creates and verifies its private table lazily
43
- on first use.
45
+ Provide a MySQL URL that includes a database name. Building the factory
46
+ validates settings locally and opens no pool. `checkConnection()` optionally
47
+ probes the shared database with a read-only query. It reuses an existing
48
+ runtime pool or opens and releases a temporary pool. The first storage
49
+ operation binds its database and creates or verifies
50
+ its private table lazily.
44
51
 
45
52
  <!-- docs-snippet-path: packages/storage-mysql/src/index.ts -->
46
53
 
@@ -74,7 +81,7 @@ try {
74
81
  if (stored?.value !== "task-42") throw new Error("The record was not stored.");
75
82
  } finally {
76
83
  await records.close();
77
- factory.close();
84
+ await factory.close();
78
85
  }
79
86
  ```
80
87
 
@@ -83,8 +90,9 @@ require TLS and provide the issuing CA explicitly; do not enable certificate
83
90
  verification without the CA material needed by your managed MySQL endpoint.
84
91
 
85
92
  For a multitenant application, assign each complete generated `TenantId` to a
86
- different database. The factory creates one pool per configured tenant and
87
- selects that pool before it opens a table or starts a transaction:
93
+ different database. The factory resolves each tenant's database and opens
94
+ its pool on first use; concurrent first uses share the binding. It selects
95
+ that pool before opening a table or starting a transaction:
88
96
 
89
97
  ```ts
90
98
  import { create } from "@bufbuild/protobuf";
@@ -95,6 +103,7 @@ const acme = create(TenantIdSchema, { kind: { case: "value", value: "acme" } });
95
103
  const globex = create(TenantIdSchema, { kind: { case: "value", value: "globex" } });
96
104
 
97
105
  const factory = await MysqlStorageFactory.newBuilder()
106
+ .setOptions({ url: "mysql://user:password@db/shared" })
98
107
  .setTenantOptions([
99
108
  { tenantId: acme, options: { url: "mysql://user:password@db/acme" } },
100
109
  { tenantId: globex, options: { url: "mysql://user:password@db/globex" } },
@@ -102,6 +111,12 @@ const factory = await MysqlStorageFactory.newBuilder()
102
111
  .build();
103
112
  ```
104
113
 
114
+ Alternatively, `setTenantResolver(async (tenantId) => options)` resolves each
115
+ tenant's destination on first use. Fixed tenant entries and a resolver cannot
116
+ be combined. Either mode requires shared `setOptions`; tenants must use
117
+ distinct databases. Shared and tenant settings may point to the same database
118
+ only when their physical table families do not collide.
119
+
105
120
  Use a dedicated database account. The account must be able to create and
106
121
  inspect the adapter tables and perform normal reads and writes. Do not commit
107
122
  connection URLs or credentials.
@@ -123,8 +138,11 @@ Entity commits use independent ordered records on InnoDB, MyISAM, and Aria.
123
138
  A failed operation can leave its completed prefix; an identical Entity retry
124
139
  reuses prepared versions and Event IDs. It supports primitive and structured
125
140
  storage IDs. Declared columns support strings, booleans, integral Protobuf
126
- numbers, enums, bytes, messages, `Timestamp`, and `Version`. Spine JVM JDBC
127
- does not support `float` or `double` record columns, so this adapter rejects
141
+ numbers, enums, bytes, messages, `Timestamp`, and `Version`. The provider-only
142
+ live Agent commit is a separate InnoDB transaction: it conditionally checks
143
+ the initial Entity version and complete model preferences before committing
144
+ any changed state, final audit, and preferences together. Spine JVM JDBC does
145
+ not support `float` or `double` record columns, so this adapter rejects
128
146
  them too.
129
147
 
130
148
  Indexed `Timestamp` columns store epoch nanoseconds in signed 64-bit `BIGINT`.
@@ -224,25 +242,15 @@ operations plan.
224
242
  ## ⚠️ Before production
225
243
 
226
244
  Use a dedicated database and account, protect the connection URL, configure
227
- TLS, and plan backups, monitoring, and migrations. Indexed `bigint` values must
245
+ TLS, and plan backups and monitoring. Indexed `bigint` values must
228
246
  fit the exact signed 64-bit MySQL range. PostgreSQL is provided separately by
229
247
  [`@spine-event-engine/storage-postgres`](https://github.com/SpineEventEngine/spine-ts/blob/master/packages/storage-postgres/README.md).
230
248
 
231
- Before starting this corrected layout against an existing database, run the
232
- legacy-layout inventory for every configured tenant database:
233
-
234
- ```sh
235
- pnpm --dir packages/storage-mysql inventory:legacy -- \
236
- --url 'mysql://user:password@127.0.0.1:3306/tenant_a' \
237
- --url 'mysql://user:password@127.0.0.1:3306/tenant_b'
238
- ```
239
-
240
- The command exits nonzero if a database is unreachable or contains the old
241
- `_scope`, `_revision`, or compound scope key. Do not start the corrected
242
- runtime until it passes. The factory repeats this check for every configured
243
- database before it becomes usable. The runtime does not read both layouts or choose
244
- between rows that old Bounded Context partitions would collapse onto the same
245
- new `ID`; migrate those rows offline and stop on every conflict.
249
+ Factory construction validates configuration without connecting. Explicit preparation
250
+ or first use checks the selected record families; it does not scan unrelated
251
+ tables. Existing tables must satisfy the expected layout. See the
252
+ [storage layout reference](https://github.com/SpineEventEngine/spine-ts/blob/master/docs/STORAGE_LAYOUT.md#6-startup-sequence) for
253
+ creation and compatibility-check timing.
246
254
 
247
255
  ## 🔗 Learn more
248
256
 
package/REFERENCE.md CHANGED
@@ -5,6 +5,7 @@ This reference is for coding agents configuring the supported MySQL storage adap
5
5
  ## Public entry point
6
6
 
7
7
  Import `MysqlStorageFactory`, `MysqlStorageOptions`, `MysqlTenantStorageOptions`,
8
+ `MysqlTenantResolver`,
8
9
  `MysqlEntityStorageHandle`, `MysqlStorageFactoryBuilder`,
9
10
  `MysqlCreateOperation`, `CreateOperationFactory`, `MysqlTableSpec`,
10
11
  `MysqlColumnSpec`, `MysqlStorageConfigurationError`,
@@ -15,12 +16,27 @@ Import `MysqlStorageFactory`, `MysqlStorageOptions`, `MysqlTenantStorageOptions`
15
16
  ## Connection and schema
16
17
 
17
18
  `MysqlStorageFactory.newBuilder().setOptions(options).build()` configures one
18
- single-tenant database. `setTenantOptions(entries)` configures one distinct
19
- database and pool per complete generated `TenantId`. The factory selects
20
- the matching pool before table, query, transaction, or lock work.
21
- `setStringifierRegistry(registry)` configures reversible mappings for
22
- message-valued IDs and ordinary message columns; the builder snapshots the
23
- registry so later caller changes do not alter stored or queried values.
19
+ shared database without connecting. `setTenantOptions(entries)` configures
20
+ distinct databases for complete generated `TenantId` values;
21
+ `setTenantResolver(resolver)` selects them asynchronously on first use. Fixed
22
+ entries and a resolver are mutually exclusive. Shared options are required in
23
+ both modes. The first storage operation binds each database and its pool;
24
+ concurrent first uses share that binding, while a failed binding can retry.
25
+ `checkConnection()` probes only the shared database with `SELECT 1`, performs
26
+ no schema checks or DDL, and releases a temporary pool unless runtime work
27
+ already bound one. Successful checks are remembered; failed checks can retry.
28
+ The provider-only `StoragePreparations` port accepts declared Record, current
29
+ Entity and enabled history, or surviving Agent audit requirements. Its `check`
30
+ mode reads physical metadata without creating tables or indexes. Its `create`
31
+ mode creates missing structures and verifies their complete layout. Both modes
32
+ reuse a bound runtime pool or release temporary pools, and compatible results
33
+ are shared with later ordinary use. A failed attempt remains retryable.
34
+ The default shared registry converts message-valued IDs and ordinary message
35
+ columns using generated descriptors registered on module import.
36
+ `setStringifierRegistry(registry)` accepts a custom registry; the builder
37
+ snapshots it so later caller changes do not alter stored or queried values.
38
+ `setEventStoreTable(contextName, table, role?)` selects one physical Event Store
39
+ table for the exact bounded-context name and domain or system role.
24
40
  `Identifiers` choose the storage ID representation; the configured
25
41
  `StringifierRegistry` supplies the matching reversible representation for
26
42
  message-valued IDs and declared message columns. `RecordQuery<I>` statically
@@ -28,7 +44,8 @@ types IDs only. Filter names and values are runtime inputs: MySQL checks the
28
44
  name against the declared columns and maps each value through the corresponding
29
45
  descriptor/column mapping, rather than accepting an application-constructed
30
46
  provider string.
31
- Per-family tables are created and verified lazily on first use. Options support
47
+ Without explicit preparation, per-family tables are created and verified lazily
48
+ on first use. Options support
32
49
  `connectionLimit`, `connectTimeoutMs`, and TLS material. Failure to validate
33
50
  configuration throws `MysqlStorageConfigurationError`; inaccessible connections
34
51
  are reported as `MysqlStorageConnectionError`; an
@@ -45,22 +62,20 @@ one-byte binary collation, such as `latin1_bin`, and can store only IDs
45
62
  representable in that character set. An `utf8mb4` ID of that declared width
46
63
  cannot be converted to MyISAM.
47
64
 
48
- Before deployment, run `pnpm --dir packages/storage-mysql inventory:legacy --
49
- --url <database-url>` once for every configured tenant database. The command
50
- fails closed on connection errors, `_scope`, `_revision`, or an old primary key
51
- containing `_scope`. Passing this inventory is a startup prerequisite for an
52
- upgraded application. Factory build repeats the inspection for every configured
53
- database; the runtime has no dual-layout reader or automatic
54
- conflict winner.
65
+ Factory build and `checkConnection()` do not scan unrelated tables. Requested
66
+ record families are checked when normal storage operations first use them.
55
67
 
56
68
  ## Lifecycle and tenancy
57
69
 
58
- `close(): void` marks the factory and its live handles closed and starts pool
59
- draining. Callers do not await it. A record handle closes independently. A
60
- single-tenant factory has one database. A multitenant factory requires a
61
- complete generated `TenantId` on each operation and routes it to its configured
62
- database. Bounded Context names are diagnostic only and never partition rows,
63
- tables, locks, or queries.
70
+ `close(): Promise<void>` immediately fences new public operations, waits for
71
+ complete admitted record, Entity, Agent, and commit work, then closes live
72
+ handles and drains pools. Await it to
73
+ observe cleanup failures; repeated calls return the same completion. A record
74
+ handle closes independently. Shared operations use the configured shared
75
+ destination. Creating a multitenant storage handle requires a complete
76
+ generated `TenantId` in its `StorageContext`; that captured tenant selects the
77
+ database for operations through the handle. Bounded Context names are
78
+ diagnostic only and never partition rows, tables, locks, or queries.
64
79
 
65
80
  Each Entity source and history family has an independent table. Top-level
66
81
  provider error messages and public responses omit connection URLs,
@@ -153,30 +168,15 @@ misordered, or otherwise incompatible same-name indexes reject when the handle
153
168
  opens. Pages use bounded native SQL chunks and sum serialized entry bytes; a
154
169
  fetched chunk can be larger than the returned byte budget.
155
170
 
156
- ## Agent execution
157
-
158
- Agent execution conformance is exercised with MySQL 5.7 and 8.4, and MariaDB 11.4.
159
-
160
- Agent repositories require InnoDB. The execution handle rejects a nontransactional
161
- engine before accepting Agent work; the existing engine choices for other Entity
162
- families are unchanged. Execution and per-instance pending records use complete
163
- binary ordering keys and validated composite indexes.
164
-
165
- One connection transaction checks the claim and initial Entity Version, then
166
- writes state, mandatory history, preferences and outgoing Command obligations. Emitted
167
- domain Events enter immutable Agent history and are handed to the normal EventBus
168
- after completion without a saved delivery phase. Connection
169
- binding is scoped to that asynchronous operation. Encoded execution,
170
- per-instance, and Agent history records must each fit the 65,535-byte BLOB limit. The runtime must
171
- check its response reservation against the provider limits before inference.
172
- Reopening a factory can read the saved work. No transaction remains open during
173
- a model request.
174
-
175
- `MysqlStorageSchemaError` reports incompatible layouts,
176
- `MysqlStorageDataError` reports stored bytes that cannot be decoded, and
177
- `MysqlStorageOperationError` reports sanitized bounds, query, collision, and
178
- driver-operation failures. Custom creation uses `useOperationFactory()`; its
179
- resolved `MysqlTableSpec` has the same native column types and family-specific
180
- naming as default DDL. A grouped family uses its explicit grouped override or
181
- grouped default; an ungrouped family uses its explicit record override or
182
- ungrouped default. An ungrouped override never aliases a grouped family.
171
+ ## Agent live persistence
172
+
173
+ The live Agent path is exercised on MySQL and MariaDB. Agent repositories
174
+ require transactional InnoDB tables for atomic Agent commits. The handle
175
+ rejects a nontransactional engine before accepting Agent work; other Entity
176
+ families retain their configured engine behavior. `appendAll()` commits an
177
+ immutable Agent history group in one transaction. `commitAgent()` compares
178
+ the exact Entity image and model preferences, then writes accepted state,
179
+ preference, and history changes atomically. A no-op or preference-only turn
180
+ can leave the Entity Version unchanged. The separate typed receipt records
181
+ admission, not executable work for replay. Connection binding is scoped to an
182
+ asynchronous operation; no transaction stays open during a model request.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { MysqlStorageConfigurationError, MysqlStorageConnectionError, MysqlStorageDataError, MysqlStorageFactory, MysqlStorageOperationError, MysqlStorageSchemaError, type CreateOperationFactory, type MysqlColumnSpec, type MysqlCreateOperation, type MysqlStorageFactoryBuilder, type MysqlStorageOptions, type MysqlTenantStorageOptions, type MysqlTableSpec, } from "./mysql/storage-factory.js";
1
+ export { MysqlStorageConfigurationError, MysqlStorageConnectionError, MysqlStorageDataError, MysqlStorageFactory, MysqlStorageOperationError, MysqlStorageSchemaError, type CreateOperationFactory, type MysqlColumnSpec, type MysqlCreateOperation, type MysqlStorageFactoryBuilder, type MysqlStorageOptions, type MysqlTenantStorageOptions, type MysqlTenantResolver, type MysqlTableSpec, } from "./mysql/storage-factory.js";
2
2
  export type { MysqlEntityStorageHandle } from "./mysql/entity-history.js";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,GACpB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,GAQxB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,GASxB,MAAM,4BAA4B,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import type { AgentHistoryEntry } from "@spine-event-engine/proto/agent";
2
- import type { AgentHistoryRecord } from "@spine-event-engine/proto/generated/spine/server/agent/history_record_pb.js";
3
- import { type AgentHistoryPage, type AgentHistoryRead, type AgentHistoryStorage, type AgentHistoryStorageInput } from "@spine-event-engine/storage/provider";
4
- import { MysqlRecordStorage } from "./record-storage.js";
2
+ import { type AgentHistoryRecord } from "@spine-event-engine/proto/generated/spine/server/agent/history_record_pb.js";
3
+ import { type AgentHistoryCapacity, type AgentHistoryPage, type AgentHistoryRead, type AgentHistoryStorage, type AgentHistoryStorageInput } from "@spine-event-engine/storage/provider";
4
+ import { MysqlRecordStorage, type OnPublicOperation } from "./record-storage.js";
5
+ import { MysqlAgentTransaction } from "./agent-transaction.js";
5
6
  /**
6
7
  * Hashes complete identities into bounded physical IDs and indexed scope keys.
7
8
  */
@@ -14,6 +15,10 @@ export declare const AgentHistoryHash: {
14
15
  */
15
16
  value(value: string): string;
16
17
  };
18
+ /**
19
+ * Declares the complete native indexes required by MySQL Agent history.
20
+ */
21
+ export declare const AgentHistoryIndexes: readonly [readonly ["agent_history_full", readonly ["scope_digest", "order_key"]], readonly ["agent_history_category", readonly ["scope_digest", "category", "order_key"]], readonly ["agent_history_conversation", readonly ["scope_digest", "conversation_digest", "order_key"]]];
17
22
  /**
18
23
  * Stores Agent history in the shared MySQL immutable record family.
19
24
  *
@@ -23,13 +28,36 @@ export declare class MysqlAgentHistory<Id> implements AgentHistoryStorage<Id> {
23
28
  #private;
24
29
  private readonly input;
25
30
  private readonly records;
31
+ private readonly onAdmit;
32
+ private readonly transaction?;
33
+ /**
34
+ * Maximum immutable Agent history record bytes supported by MySQL.
35
+ */
36
+ readonly capacity: AgentHistoryCapacity;
26
37
  /**
27
38
  * Binds one typed Agent repository to the provider record handle.
28
39
  *
29
40
  * @param input Repository and complete tenant scope.
30
41
  * @param records Native record-family storage.
42
+ * @param onAdmit Admits complete public history operations.
43
+ * @param transaction Coordinates native immutable audit groups.
44
+ */
45
+ constructor(input: AgentHistoryStorageInput<Id>, records: MysqlRecordStorage<string, AgentHistoryRecord>, onAdmit?: OnPublicOperation, transaction?: MysqlAgentTransaction | undefined);
46
+ /**
47
+ * Writes atomically writes captured immutable rows in the selected tenant database.
48
+ * @param entityId Typed Agent identifier.
49
+ * @param entries Complete Agent audit group.
50
+ * @returns Completion after the native transaction commits.
51
+ */
52
+ appendAll(entityId: Id, entries: readonly AgentHistoryEntry[]): Promise<void>;
53
+ /**
54
+ * Performs one admitted Agent audit group on a native connection.
55
+ *
56
+ * @param entityId Typed Entity identifier.
57
+ * @param entries Complete immutable history group.
58
+ * @returns Completion after the complete immutable audit group commits atomically.
31
59
  */
32
- constructor(input: AgentHistoryStorageInput<Id>, records: MysqlRecordStorage<string, AgentHistoryRecord>);
60
+ private appendAllAdmitted;
33
61
  /**
34
62
  * Writes one original entry or confirms byte-identical content.
35
63
  *
@@ -38,6 +66,14 @@ export declare class MysqlAgentHistory<Id> implements AgentHistoryStorage<Id> {
38
66
  * @returns Completion after immutable storage confirms the entry.
39
67
  */
40
68
  append(entityId: Id, entry: AgentHistoryEntry): Promise<void>;
69
+ /**
70
+ * Executes an admitted provider operation.
71
+ *
72
+ * @param entityId Typed Agent identifier.
73
+ * @param entry Original entry.
74
+ * @returns Completion after immutable storage.
75
+ */
76
+ private appendAdmitted;
41
77
  /**
42
78
  * Reads a bounded indexed page in full Timestamp/category/UTF-8 order.
43
79
  *
@@ -46,9 +82,14 @@ export declare class MysqlAgentHistory<Id> implements AgentHistoryStorage<Id> {
46
82
  */
47
83
  read(request: AgentHistoryRead<Id>): Promise<AgentHistoryPage>;
48
84
  /**
49
-
85
+ * Executes an admitted provider operation.
86
+ *
87
+ * @param request Typed history page request.
88
+ * @returns Original entries and continuation status.
89
+ */
90
+ private readAdmitted;
91
+ /**
50
92
  * Closes this handle without deleting stored records.
51
-
52
93
  */
53
94
  close(): void;
54
95
  /**
@@ -95,9 +136,7 @@ export declare class MysqlAgentHistory<Id> implements AgentHistoryStorage<Id> {
95
136
  */
96
137
  private key;
97
138
  /**
98
-
99
139
  * Rejects calls after this handle closes.
100
-
101
140
  */
102
141
  private requireOpen;
103
142
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-history.d.ts","sourceRoot":"","sources":["../../src/mysql/agent-history.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6EAA6E,CAAC;AACtH,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;;;OAKG;iBACU,MAAM,GAAG,MAAM;CAG7B,CAAC;AAEF;;;;GAIG;AACH,qBAAa,iBAAiB,CAAC,EAAE,CAAE,YAAW,mBAAmB,CAAC,EAAE,CAAC;;IAoBjE,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B;;;;;OAKG;gBAEgB,KAAK,EAAE,wBAAwB,CAAC,EAAE,CAAC,EACnC,OAAO,EAAE,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAG1E;;;;;;OAMG;IACG,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE;;;;;OAKG;IACG,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAYpE;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAMb;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAIb;;;;OAIG;YACW,UAAU;IAexB;;;;;;;;OAQG;YACW,KAAK;IA4BnB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAkBrB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAQpB;;;;;OAKG;IACH,OAAO,CAAC,GAAG;IAMX;;;;OAIG;IACH,OAAO,CAAC,WAAW;CAGpB"}
1
+ {"version":3,"file":"agent-history.d.ts","sourceRoot":"","sources":["../../src/mysql/agent-history.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,6EAA6E,CAAC;AACrF,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAG/D;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;;;OAKG;iBACU,MAAM,GAAG,MAAM;CAG7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,qRAItB,CAAC;AAEX;;;;GAIG;AACH,qBAAa,iBAAiB,CAAC,EAAE,CAAE,YAAW,mBAAmB,CAAC,EAAE,CAAC;;IAyBjE,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IA3B/B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAiD;IAYxF;;;;;;;OAOG;gBAEgB,KAAK,EAAE,wBAAwB,CAAC,EAAE,CAAC,EACnC,OAAO,EAAE,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACvD,OAAO,GAAE,iBAAoC,EAC7C,WAAW,CAAC,EAAE,qBAAqB,GAAG,SAAS;IAGlE;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7E;;;;;;OAMG;YACW,iBAAiB;IA+B/B;;;;;;OAMG;IACG,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE;;;;;;OAMG;YACW,cAAc;IAY5B;;;;;OAKG;IACG,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIpE;;;;;OAKG;YACW,YAAY;IAY1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAOb;;;;OAIG;YACW,UAAU;IAMxB;;;;;;;;OAQG;YACW,KAAK;IA4BnB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAkBrB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAQpB;;;;;OAKG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACH,OAAO,CAAC,WAAW;CAGpB"}
@@ -12,9 +12,12 @@
12
12
  * the License.
13
13
  */
14
14
  import { createHash } from "node:crypto";
15
+ import { clone, toBinary } from "@bufbuild/protobuf";
16
+ import { AgentHistoryRecordSchema, } from "@spine-event-engine/proto/generated/spine/server/agent/history_record_pb.js";
15
17
  import { AgentHistoryKeys, AgentHistoryPages, } from "@spine-event-engine/storage/provider";
16
18
  import { AgentHistoryRecords } from "@spine-event-engine/storage/provider";
17
19
  import { MysqlRecordStorage } from "./record-storage.js";
20
+ import { MysqlAgentTransaction } from "./agent-transaction.js";
18
21
  import { AgentHistoryIndexBytes } from "./table-spec.js";
19
22
  /**
20
23
  * Hashes complete identities into bounded physical IDs and indexed scope keys.
@@ -30,6 +33,14 @@ export const AgentHistoryHash = {
30
33
  return createHash("sha256").update(value, "utf8").digest("hex");
31
34
  },
32
35
  };
36
+ /**
37
+ * Declares the complete native indexes required by MySQL Agent history.
38
+ */
39
+ export const AgentHistoryIndexes = [
40
+ ["agent_history_full", ["scope_digest", "order_key"]],
41
+ ["agent_history_category", ["scope_digest", "category", "order_key"]],
42
+ ["agent_history_conversation", ["scope_digest", "conversation_digest", "order_key"]],
43
+ ];
33
44
  /**
34
45
  * Stores Agent history in the shared MySQL immutable record family.
35
46
  *
@@ -38,14 +49,18 @@ export const AgentHistoryHash = {
38
49
  export class MysqlAgentHistory {
39
50
  input;
40
51
  records;
52
+ onAdmit;
53
+ transaction;
54
+ /**
55
+ * Maximum immutable Agent history record bytes supported by MySQL.
56
+ */
57
+ capacity = Object.freeze({ historyRecordBytes: 65_535 });
41
58
  /**
42
59
  * Records whether this handle accepts calls.
43
60
  */
44
61
  #open = true;
45
62
  /**
46
-
47
63
  * Reuses one table and index preparation promise.
48
-
49
64
  */
50
65
  #ready;
51
66
  /**
@@ -53,10 +68,52 @@ export class MysqlAgentHistory {
53
68
  *
54
69
  * @param input Repository and complete tenant scope.
55
70
  * @param records Native record-family storage.
71
+ * @param onAdmit Admits complete public history operations.
72
+ * @param transaction Coordinates native immutable audit groups.
56
73
  */
57
- constructor(input, records) {
74
+ constructor(input, records, onAdmit = (work) => work(), transaction) {
58
75
  this.input = input;
59
76
  this.records = records;
77
+ this.onAdmit = onAdmit;
78
+ this.transaction = transaction;
79
+ }
80
+ /**
81
+ * Writes atomically writes captured immutable rows in the selected tenant database.
82
+ * @param entityId Typed Agent identifier.
83
+ * @param entries Complete Agent audit group.
84
+ * @returns Completion after the native transaction commits.
85
+ */
86
+ appendAll(entityId, entries) {
87
+ return this.onAdmit(() => this.appendAllAdmitted(entityId, entries));
88
+ }
89
+ /**
90
+ * Performs one admitted Agent audit group on a native connection.
91
+ *
92
+ * @param entityId Typed Entity identifier.
93
+ * @param entries Complete immutable history group.
94
+ * @returns Completion after the complete immutable audit group commits atomically.
95
+ */
96
+ async appendAllAdmitted(entityId, entries) {
97
+ this.requireOpen();
98
+ const key = this.key(entityId);
99
+ const rows = entries.map((entry) => {
100
+ if (AgentHistoryKeys.indexValue(AgentHistoryKeys.fromEntry(entry)).length >
101
+ AgentHistoryIndexBytes)
102
+ throw new RangeError("Agent history ordering key exceeds the MySQL index capacity.");
103
+ const row = clone(AgentHistoryRecordSchema, AgentHistoryRecords.record(this.input.stateType, key, entry));
104
+ if (toBinary(AgentHistoryRecordSchema, row).length > 65_535)
105
+ throw new RangeError("Agent history record exceeds the MySQL row capacity.");
106
+ return row;
107
+ });
108
+ if (rows.length === 0)
109
+ return;
110
+ if (this.transaction === undefined)
111
+ throw new Error("MySQL Agent history transaction is unavailable.");
112
+ await this.ready();
113
+ await this.transaction.commit([this.records.tableName], (connection) => this.records.withConnection(connection, async () => {
114
+ for (const row of rows)
115
+ await this.records.writeImmutable(row);
116
+ }));
60
117
  }
61
118
  /**
62
119
  * Writes one original entry or confirms byte-identical content.
@@ -66,6 +123,16 @@ export class MysqlAgentHistory {
66
123
  * @returns Completion after immutable storage confirms the entry.
67
124
  */
68
125
  async append(entityId, entry) {
126
+ return this.onAdmit(() => this.appendAdmitted(entityId, entry));
127
+ }
128
+ /**
129
+ * Executes an admitted provider operation.
130
+ *
131
+ * @param entityId Typed Agent identifier.
132
+ * @param entry Original entry.
133
+ * @returns Completion after immutable storage.
134
+ */
135
+ async appendAdmitted(entityId, entry) {
69
136
  this.requireOpen();
70
137
  if (AgentHistoryKeys.indexValue(AgentHistoryKeys.fromEntry(entry)).length > AgentHistoryIndexBytes)
71
138
  throw new RangeError("Agent history ordering key exceeds the MySQL index capacity.");
@@ -79,6 +146,15 @@ export class MysqlAgentHistory {
79
146
  * @returns Original entries and continuation status.
80
147
  */
81
148
  async read(request) {
149
+ return this.onAdmit(() => this.readAdmitted(request));
150
+ }
151
+ /**
152
+ * Executes an admitted provider operation.
153
+ *
154
+ * @param request Typed history page request.
155
+ * @returns Original entries and continuation status.
156
+ */
157
+ async readAdmitted(request) {
82
158
  this.requireOpen();
83
159
  await this.ready();
84
160
  const agentKey = this.key(request.entityId);
@@ -87,9 +163,7 @@ export class MysqlAgentHistory {
87
163
  return AgentHistoryPages.read(request, after, (cursor, limit) => this.fetch(agentKey, request, cursor, limit));
88
164
  }
89
165
  /**
90
-
91
166
  * Closes this handle without deleting stored records.
92
-
93
167
  */
94
168
  close() {
95
169
  if (!this.#open)
@@ -103,7 +177,10 @@ export class MysqlAgentHistory {
103
177
  * @returns Shared preparation promise for this handle.
104
178
  */
105
179
  ready() {
106
- return (this.#ready ??= this.initialize());
180
+ return (this.#ready ??= this.initialize().catch((error) => {
181
+ this.#ready = undefined;
182
+ throw error;
183
+ }));
107
184
  }
108
185
  /**
109
186
  * Creates each native index idempotently on the shared record family.
@@ -112,17 +189,8 @@ export class MysqlAgentHistory {
112
189
  */
113
190
  async initialize() {
114
191
  await this.records.prepare();
115
- await this.records.ensureHistoryIndex("agent_history_full", ["scope_digest", "order_key"]);
116
- await this.records.ensureHistoryIndex("agent_history_category", [
117
- "scope_digest",
118
- "category",
119
- "order_key",
120
- ]);
121
- await this.records.ensureHistoryIndex("agent_history_conversation", [
122
- "scope_digest",
123
- "conversation_digest",
124
- "order_key",
125
- ]);
192
+ for (const [name, columns] of AgentHistoryIndexes)
193
+ await this.records.ensureHistoryIndex(name, columns);
126
194
  }
127
195
  /**
128
196
  * Reads a bounded native page with complete scope and view predicates.
@@ -200,9 +268,7 @@ export class MysqlAgentHistory {
200
268
  return key;
201
269
  }
202
270
  /**
203
-
204
271
  * Rejects calls after this handle closes.
205
-
206
272
  */
207
273
  requireOpen() {
208
274
  if (!this.#open)
@@ -1 +1 @@
1
- {"version":3,"file":"agent-history.js","sourceRoot":"","sources":["../../src/mysql/agent-history.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-history.js","sourceRoot":"","sources":["../../src/mysql/agent-history.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,12 @@ export declare class MysqlAgentTransaction {
22
22
  * @returns Returns the work result.
23
23
  */
24
24
  commit<T>(tables: readonly string[], work: (connection: PoolConnection) => Promise<T>): Promise<T>;
25
+ /**
26
+ * Checks every declared live Agent table for native transaction support.
27
+ * @param tables Participating physical table names.
28
+ * @returns Completion after a read-only InnoDB inspection.
29
+ */
30
+ check(tables: readonly string[]): Promise<void>;
25
31
  /**
26
32
  * Determines whether every participating table supports transactions.
27
33
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-transaction.d.ts","sourceRoot":"","sources":["../../src/mysql/agent-transaction.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAEpE;;GAEG;AACH,qBAAa,qBAAqB;IAS9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B;;;;OAIG;gBAEgB,WAAW,EAAE;QAC5B,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;QACnC,OAAO,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;KAC3C;IAGH;;;;;;;OAOG;IACG,MAAM,CAAC,CAAC,EACZ,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,IAAI,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAC/C,OAAO,CAAC,CAAC,CAAC;IAYb;;;;;;OAMG;YACW,gBAAgB;IAa9B;;;;;;;OAOG;YACW,iBAAiB;IAmB/B;;;;;OAKG;IACH,OAAO,CAAC,UAAU;CAOnB"}
1
+ {"version":3,"file":"agent-transaction.d.ts","sourceRoot":"","sources":["../../src/mysql/agent-transaction.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AAEpE;;GAEG;AACH,qBAAa,qBAAqB;IAS9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B;;;;OAIG;gBAEgB,WAAW,EAAE;QAC5B,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;QACnC,OAAO,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;KAC3C;IAGH;;;;;;;OAOG;IACG,MAAM,CAAC,CAAC,EACZ,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,IAAI,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAC/C,OAAO,CAAC,CAAC,CAAC;IAYb;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD;;;;;;OAMG;YACW,gBAAgB;IAa9B;;;;;;;OAOG;YACW,iBAAiB;IAmB/B;;;;;OAKG;IACH,OAAO,CAAC,UAAU;CAOnB"}
@@ -45,6 +45,21 @@ export class MysqlAgentTransaction {
45
45
  this.connections.release(connection);
46
46
  }
47
47
  }
48
+ /**
49
+ * Checks every declared live Agent table for native transaction support.
50
+ * @param tables Participating physical table names.
51
+ * @returns Completion after a read-only InnoDB inspection.
52
+ */
53
+ async check(tables) {
54
+ const connection = await this.connections.acquire();
55
+ try {
56
+ if (!(await this.allTransactional(connection, tables)))
57
+ throw new Error("MySQL Agent execution requires transactional record tables.");
58
+ }
59
+ finally {
60
+ this.connections.release(connection);
61
+ }
62
+ }
48
63
  /**
49
64
  * Determines whether every participating table supports transactions.
50
65
  *