@pellux/goodvibes-sdk 0.25.1 → 0.25.2

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 (34) hide show
  1. package/dist/_internal/daemon/otlp-protobuf.d.ts +3 -0
  2. package/dist/_internal/daemon/otlp-protobuf.d.ts.map +1 -0
  3. package/dist/_internal/daemon/otlp-protobuf.js +968 -0
  4. package/dist/_internal/daemon/telemetry-routes.d.ts.map +1 -1
  5. package/dist/_internal/daemon/telemetry-routes.js +22 -13
  6. package/dist/_internal/platform/version.js +1 -1
  7. package/package.json +1 -1
  8. package/dist/_internal/platform/runtime/contracts/index.d.ts +0 -40
  9. package/dist/_internal/platform/runtime/contracts/index.d.ts.map +0 -1
  10. package/dist/_internal/platform/runtime/contracts/index.js +0 -133
  11. package/dist/_internal/platform/runtime/contracts/migrations/index.d.ts +0 -75
  12. package/dist/_internal/platform/runtime/contracts/migrations/index.d.ts.map +0 -1
  13. package/dist/_internal/platform/runtime/contracts/migrations/index.js +0 -158
  14. package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts +0 -57
  15. package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts.map +0 -1
  16. package/dist/_internal/platform/runtime/contracts/migrations/schemas.js +0 -157
  17. package/dist/_internal/platform/runtime/contracts/types.d.ts +0 -123
  18. package/dist/_internal/platform/runtime/contracts/types.d.ts.map +0 -1
  19. package/dist/_internal/platform/runtime/contracts/types.js +0 -41
  20. package/dist/_internal/platform/runtime/contracts/validators/event-envelope.d.ts +0 -24
  21. package/dist/_internal/platform/runtime/contracts/validators/event-envelope.d.ts.map +0 -1
  22. package/dist/_internal/platform/runtime/contracts/validators/event-envelope.js +0 -104
  23. package/dist/_internal/platform/runtime/contracts/validators/index.d.ts +0 -11
  24. package/dist/_internal/platform/runtime/contracts/validators/index.d.ts.map +0 -1
  25. package/dist/_internal/platform/runtime/contracts/validators/index.js +0 -10
  26. package/dist/_internal/platform/runtime/contracts/validators/runtime-state.d.ts +0 -23
  27. package/dist/_internal/platform/runtime/contracts/validators/runtime-state.d.ts.map +0 -1
  28. package/dist/_internal/platform/runtime/contracts/validators/runtime-state.js +0 -101
  29. package/dist/_internal/platform/runtime/contracts/validators/session.d.ts +0 -24
  30. package/dist/_internal/platform/runtime/contracts/validators/session.d.ts.map +0 -1
  31. package/dist/_internal/platform/runtime/contracts/validators/session.js +0 -103
  32. package/dist/_internal/platform/runtime/contracts/version.d.ts +0 -84
  33. package/dist/_internal/platform/runtime/contracts/version.d.ts.map +0 -1
  34. package/dist/_internal/platform/runtime/contracts/version.js +0 -41
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-routes.d.ts","sourceRoot":"","sources":["../../../src/_internal/daemon/telemetry-routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telemetry-routes.d.ts","sourceRoot":"","sources":["../../../src/_internal/daemon/telemetry-routes.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { buildMissingScopeBody } from './http-policy.js';
2
+ import { decodeOtlpProtobuf } from './otlp-protobuf.js';
2
3
  import { DaemonErrorCategory } from '../errors/index.js';
3
4
  function parseNumber(value) {
4
5
  if (value === null || value.trim().length === 0)
@@ -45,10 +46,9 @@ function buildFilter(url) {
45
46
  // ---------------------------------------------------------------------------
46
47
  /** Max ingest payload (4 MiB) — reject larger bodies with 413 */
47
48
  const OTLP_INGEST_MAX_BODY_BYTES = 4 * 1024 * 1024;
48
- /** Accepted content-types for OTLP/HTTP JSON only; protobuf returns 415 */
49
- const OTLP_ACCEPTED_CONTENT_TYPES = [
50
- 'application/json',
51
- ];
49
+ /** Accepted content-types for OTLP/HTTP ingest. */
50
+ const OTLP_JSON_CONTENT_TYPE = 'application/json';
51
+ const OTLP_PROTOBUF_CONTENT_TYPES = new Set(['application/x-protobuf', 'application/protobuf']);
52
52
  const OTLP_PARTIAL_SUCCESS_KEYS = {
53
53
  logs: 'partialSuccess',
54
54
  traces: 'partialSuccess',
@@ -58,18 +58,19 @@ const OTLP_PARTIAL_SUCCESS_KEYS = {
58
58
  * Validate and parse an OTLP HTTP ingest request body.
59
59
  * Returns a parsed JSON Record on success, or a Response (error) on failure.
60
60
  *
61
- * Protocol: OTLP/HTTP spec §4.2 — only application/json is accepted in this
62
- * release. application/x-protobuf returns 415; protobuf decoding is planned
63
- * for a future release.
61
+ * Protocol: OTLP/HTTP spec §4.2 — supports JSON and binary protobuf service
62
+ * requests for logs, traces, and metrics.
64
63
  */
65
- async function parseOtlpBody(req) {
64
+ async function parseOtlpBody(req, kind) {
66
65
  const contentType = (req.headers.get('content-type') ?? '').toLowerCase().split(';')[0].trim();
67
- if (!OTLP_ACCEPTED_CONTENT_TYPES.some((ct) => contentType === ct)) {
66
+ const acceptsJson = contentType === OTLP_JSON_CONTENT_TYPE;
67
+ const acceptsProtobuf = OTLP_PROTOBUF_CONTENT_TYPES.has(contentType);
68
+ if (!acceptsJson && !acceptsProtobuf) {
68
69
  return Response.json({
69
70
  error: `Unsupported Content-Type '${contentType}' for OTLP ingest`,
70
71
  code: 'UNSUPPORTED_MEDIA_TYPE',
71
72
  category: DaemonErrorCategory.BAD_REQUEST,
72
- hint: `Use 'application/json'. Protobuf decoding is not implemented in this release — planned for a future release.`,
73
+ hint: `Use '${OTLP_JSON_CONTENT_TYPE}' or 'application/x-protobuf'.`,
73
74
  }, { status: 415 });
74
75
  }
75
76
  const raw = await req.arrayBuffer();
@@ -80,6 +81,14 @@ async function parseOtlpBody(req) {
80
81
  category: DaemonErrorCategory.BAD_REQUEST,
81
82
  }, { status: 413 });
82
83
  }
84
+ if (acceptsProtobuf) {
85
+ try {
86
+ return decodeOtlpProtobuf(kind, new Uint8Array(raw));
87
+ }
88
+ catch {
89
+ return Response.json({ error: 'OTLP ingest body is not valid protobuf', code: 'INVALID_PAYLOAD', category: DaemonErrorCategory.BAD_REQUEST }, { status: 400 });
90
+ }
91
+ }
83
92
  try {
84
93
  const text = new TextDecoder().decode(raw);
85
94
  const parsed = JSON.parse(text);
@@ -289,7 +298,7 @@ export function createDaemonTelemetryRouteHandlers(context) {
289
298
  if (!auth) {
290
299
  return Response.json({ error: 'Authentication required for OTLP ingest', code: 'AUTH_REQUIRED', category: DaemonErrorCategory.AUTHENTICATION, status: 401 }, { status: 401 });
291
300
  }
292
- const bodyOrErr = await parseOtlpBody(req);
301
+ const bodyOrErr = await parseOtlpBody(req, 'logs');
293
302
  if (bodyOrErr instanceof Response)
294
303
  return bodyOrErr;
295
304
  context.ingestSink?.ingestLogs(bodyOrErr);
@@ -300,7 +309,7 @@ export function createDaemonTelemetryRouteHandlers(context) {
300
309
  if (!auth) {
301
310
  return Response.json({ error: 'Authentication required for OTLP ingest', code: 'AUTH_REQUIRED', category: DaemonErrorCategory.AUTHENTICATION, status: 401 }, { status: 401 });
302
311
  }
303
- const bodyOrErr = await parseOtlpBody(req);
312
+ const bodyOrErr = await parseOtlpBody(req, 'traces');
304
313
  if (bodyOrErr instanceof Response)
305
314
  return bodyOrErr;
306
315
  context.ingestSink?.ingestTraces(bodyOrErr);
@@ -311,7 +320,7 @@ export function createDaemonTelemetryRouteHandlers(context) {
311
320
  if (!auth) {
312
321
  return Response.json({ error: 'Authentication required for OTLP ingest', code: 'AUTH_REQUIRED', category: DaemonErrorCategory.AUTHENTICATION, status: 401 }, { status: 401 });
313
322
  }
314
- const bodyOrErr = await parseOtlpBody(req);
323
+ const bodyOrErr = await parseOtlpBody(req, 'metrics');
315
324
  if (bodyOrErr instanceof Response)
316
325
  return bodyOrErr;
317
326
  context.ingestSink?.ingestMetrics(bodyOrErr);
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- let version = '0.25.1';
3
+ let version = '0.25.2';
4
4
  try {
5
5
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', '..', 'package.json'), 'utf-8'));
6
6
  version = pkg.version ?? version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-sdk",
3
- "version": "0.25.1",
3
+ "version": "0.25.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/mgd34msu/goodvibes-sdk.git"
@@ -1,40 +0,0 @@
1
- /**
2
- * Compatibility Contracts — Module barrel and factory
3
- *
4
- * Entry point for the schema versioning, validation, and migration
5
- * infrastructure. Use `createContractRegistry()` to obtain a fully
6
- * initialized registry with all domain contracts registered.
7
- *
8
- * Usage:
9
- * ```ts
10
- * import { createContractRegistry } from './contracts/index.js';
11
- * const { registry, contracts } = createContractRegistry();
12
- * const result = contracts.get('runtimeState')?.validate(rawData);
13
- * ```
14
- *
15
- * @module contracts
16
- */
17
- export { MigrationRegistry } from './migrations/index.js';
18
- export * from './types.js';
19
- export * from './version.js';
20
- export * from './validators/index.js';
21
- import { MigrationRegistry } from './migrations/index.js';
22
- import type { SchemaContract } from './types.js';
23
- import type { ContractName } from './version.js';
24
- /**
25
- * Creates a fully initialized contract registry with all domain migration
26
- * steps registered and SchemaContract instances built for each domain.
27
- *
28
- * Each SchemaContract provides:
29
- * - `validate(data)` — runtime shape validation returning a ValidationResult
30
- * - `migrate(data, fromVersion)` — migration chain execution via MigrationRegistry
31
- *
32
- * @returns An object containing:
33
- * - `registry` — the MigrationRegistry with all steps registered
34
- * - `contracts` — a Map of contract name → SchemaContract
35
- */
36
- export declare function createContractRegistry(): {
37
- registry: MigrationRegistry;
38
- contracts: Map<ContractName, SchemaContract>;
39
- };
40
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/contracts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAYjD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,GAAG,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;CAC9C,CAsGA"}
@@ -1,133 +0,0 @@
1
- /**
2
- * Compatibility Contracts — Module barrel and factory
3
- *
4
- * Entry point for the schema versioning, validation, and migration
5
- * infrastructure. Use `createContractRegistry()` to obtain a fully
6
- * initialized registry with all domain contracts registered.
7
- *
8
- * Usage:
9
- * ```ts
10
- * import { createContractRegistry } from './contracts/index.js';
11
- * const { registry, contracts } = createContractRegistry();
12
- * const result = contracts.get('runtimeState')?.validate(rawData);
13
- * ```
14
- *
15
- * @module contracts
16
- */
17
- export { MigrationRegistry } from './migrations/index.js';
18
- export * from './types.js';
19
- export * from './version.js';
20
- export * from './validators/index.js';
21
- import { MigrationRegistry } from './migrations/index.js';
22
- import { SCHEMA_VERSIONS, MIN_SUPPORTED_VERSIONS } from './version.js';
23
- import { getRuntimeStateMigrationSteps, getEventEnvelopeMigrationSteps, getSessionMigrationSteps, getPluginManifestMigrationSteps, getTaskRecordMigrationSteps, } from './migrations/schemas.js';
24
- import { validateRuntimeState } from './validators/runtime-state.js';
25
- import { validateEventEnvelope } from './validators/event-envelope.js';
26
- import { validateSession } from './validators/session.js';
27
- /**
28
- * Creates a fully initialized contract registry with all domain migration
29
- * steps registered and SchemaContract instances built for each domain.
30
- *
31
- * Each SchemaContract provides:
32
- * - `validate(data)` — runtime shape validation returning a ValidationResult
33
- * - `migrate(data, fromVersion)` — migration chain execution via MigrationRegistry
34
- *
35
- * @returns An object containing:
36
- * - `registry` — the MigrationRegistry with all steps registered
37
- * - `contracts` — a Map of contract name → SchemaContract
38
- */
39
- export function createContractRegistry() {
40
- const registry = new MigrationRegistry();
41
- // Register all domain migration steps
42
- for (const step of getRuntimeStateMigrationSteps()) {
43
- registry.register('runtimeState', step);
44
- }
45
- for (const step of getEventEnvelopeMigrationSteps()) {
46
- registry.register('eventEnvelope', step);
47
- }
48
- for (const step of getSessionMigrationSteps()) {
49
- registry.register('session', step);
50
- }
51
- for (const step of getPluginManifestMigrationSteps()) {
52
- registry.register('pluginManifest', step);
53
- }
54
- for (const step of getTaskRecordMigrationSteps()) {
55
- registry.register('taskRecord', step);
56
- }
57
- const contracts = new Map();
58
- // runtimeState contract
59
- contracts.set('runtimeState', {
60
- name: 'runtimeState',
61
- currentVersion: SCHEMA_VERSIONS.runtimeState,
62
- minSupportedVersion: MIN_SUPPORTED_VERSIONS.runtimeState,
63
- validate: validateRuntimeState,
64
- migrate: (data, fromVersion) => registry.migrate('runtimeState', data, fromVersion),
65
- });
66
- // eventEnvelope contract
67
- contracts.set('eventEnvelope', {
68
- name: 'eventEnvelope',
69
- currentVersion: SCHEMA_VERSIONS.eventEnvelope,
70
- minSupportedVersion: MIN_SUPPORTED_VERSIONS.eventEnvelope,
71
- validate: validateEventEnvelope,
72
- migrate: (data, fromVersion) => registry.migrate('eventEnvelope', data, fromVersion),
73
- });
74
- // session contract
75
- contracts.set('session', {
76
- name: 'session',
77
- currentVersion: SCHEMA_VERSIONS.session,
78
- minSupportedVersion: MIN_SUPPORTED_VERSIONS.session,
79
- validate: validateSession,
80
- migrate: (data, fromVersion) => registry.migrate('session', data, fromVersion),
81
- });
82
- // pluginManifest contract
83
- contracts.set('pluginManifest', {
84
- name: 'pluginManifest',
85
- currentVersion: SCHEMA_VERSIONS.pluginManifest,
86
- minSupportedVersion: MIN_SUPPORTED_VERSIONS.pluginManifest,
87
- validate: (data) => {
88
- const errors = [];
89
- if (data === null || typeof data !== 'object' || Array.isArray(data)) {
90
- errors.push({ path: '', message: 'pluginManifest must be a non-null object', expected: 'object', actual: data === null ? 'null' : Array.isArray(data) ? 'array' : typeof data });
91
- return { valid: false, errors };
92
- }
93
- const record = data;
94
- if (typeof record['name'] !== 'string' || record['name'].length === 0) {
95
- errors.push({ path: 'name', message: "Field 'name' must be a non-empty string", expected: 'non-empty string', actual: typeof record['name'] });
96
- }
97
- if (typeof record['version'] !== 'string' || record['version'].length === 0) {
98
- errors.push({ path: 'version', message: "Field 'version' must be a non-empty string", expected: 'non-empty string', actual: typeof record['version'] });
99
- }
100
- if (!Array.isArray(record['capabilities'])) {
101
- errors.push({ path: 'capabilities', message: "Field 'capabilities' must be an array", expected: 'array', actual: typeof record['capabilities'] });
102
- }
103
- return { valid: errors.length === 0, errors, version: SCHEMA_VERSIONS.pluginManifest };
104
- },
105
- migrate: (data, fromVersion) => registry.migrate('pluginManifest', data, fromVersion),
106
- });
107
- // taskRecord contract
108
- contracts.set('taskRecord', {
109
- name: 'taskRecord',
110
- currentVersion: SCHEMA_VERSIONS.taskRecord,
111
- minSupportedVersion: MIN_SUPPORTED_VERSIONS.taskRecord,
112
- validate: (data) => {
113
- const errors = [];
114
- if (data === null || typeof data !== 'object' || Array.isArray(data)) {
115
- errors.push({ path: '', message: 'taskRecord must be a non-null object', expected: 'object', actual: data === null ? 'null' : Array.isArray(data) ? 'array' : typeof data });
116
- return { valid: false, errors };
117
- }
118
- const record = data;
119
- if (typeof record['id'] !== 'string' || record['id'].length === 0) {
120
- errors.push({ path: 'id', message: "Field 'id' must be a non-empty string", expected: 'non-empty string', actual: typeof record['id'] });
121
- }
122
- if (typeof record['type'] !== 'string' || record['type'].length === 0) {
123
- errors.push({ path: 'type', message: "Field 'type' must be a non-empty string", expected: 'non-empty string', actual: typeof record['type'] });
124
- }
125
- if (typeof record['status'] !== 'string' || record['status'].length === 0) {
126
- errors.push({ path: 'status', message: "Field 'status' must be a non-empty string", expected: 'non-empty string', actual: typeof record['status'] });
127
- }
128
- return { valid: errors.length === 0, errors, version: SCHEMA_VERSIONS.taskRecord };
129
- },
130
- migrate: (data, fromVersion) => registry.migrate('taskRecord', data, fromVersion),
131
- });
132
- return { registry, contracts };
133
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * Compatibility Contracts — Migration Registry
3
- *
4
- * The MigrationRegistry holds all registered schema migration steps and
5
- * provides path resolution and ordered execution for any version pair.
6
- *
7
- * @module contracts/migrations
8
- */
9
- import { type MigrationStep, type MigrationResult, type SchemaVersion } from '../types.js';
10
- /**
11
- * Central registry for all schema migration steps.
12
- *
13
- * Migrations are registered per contract name and resolved as an ordered
14
- * chain from a given source version to the current target version.
15
- * All migration functions must be pure (no mutations, no side effects).
16
- */
17
- export declare class MigrationRegistry {
18
- private readonly steps;
19
- /**
20
- * Registers a migration step for a given contract.
21
- *
22
- * Steps are stored in insertion order and sorted at resolution time.
23
- * Duplicate from→to pairs for the same contract are not permitted.
24
- *
25
- * @param contract - The contract name (e.g. 'runtimeState').
26
- * @param step - The migration step to register.
27
- * @throws If a step with the same from→to is already registered.
28
- */
29
- register(contract: string, step: MigrationStep): void;
30
- /**
31
- * Returns true if any migration path exists from `fromVersion` toward
32
- * a higher version for the given contract.
33
- *
34
- * @param contract - The contract name.
35
- * @param fromVersion - The source schema version to migrate from.
36
- */
37
- canMigrate(contract: string, fromVersion: SchemaVersion): boolean;
38
- /**
39
- * Resolves an ordered chain of migration steps from `from` to `to`.
40
- *
41
- * Uses a greedy forward walk: at each version, finds the step that advances
42
- * closest to the target. Throws if no complete path exists.
43
- *
44
- * @param contract - The contract name.
45
- * @param from - The starting schema version.
46
- * @param to - The target schema version.
47
- * @returns Ordered array of MigrationSteps forming the complete path.
48
- * @throws If no migration path exists between the two versions.
49
- */
50
- getMigrationPath(contract: string, from: SchemaVersion, to: SchemaVersion): MigrationStep[];
51
- /**
52
- * Migrates data from `fromVersion` to the latest version reachable via
53
- * registered steps for the given contract.
54
- *
55
- * If `fromVersion` already matches the end of the migration chain,
56
- * the data is returned as-is without transformation.
57
- *
58
- * @param contract - The contract name.
59
- * @param data - The raw data to migrate.
60
- * @param fromVersion - The schema version of the incoming data.
61
- * @returns The migrated data and the version it was migrated to.
62
- * @throws If the migration path is incomplete or a step throws.
63
- */
64
- migrate(contract: string, data: unknown, fromVersion: SchemaVersion): MigrationResult;
65
- /**
66
- * Resolves the highest version reachable from `fromVersion` by following
67
- * the chain of registered steps.
68
- */
69
- private _resolveLatestVersion;
70
- /**
71
- * Returns all registered contract names.
72
- */
73
- contractNames(): string[];
74
- }
75
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/_internal/platform/runtime/contracts/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAInB,MAAM,aAAa,CAAC;AAErB;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;IAE5D;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAiBrD;;;;;;OAMG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,GAAG,OAAO;IAKjE;;;;;;;;;;;OAWG;IACH,gBAAgB,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,aAAa,GAChB,aAAa,EAAE;IAqDlB;;;;;;;;;;;;OAYG;IACH,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,aAAa,GACzB,eAAe;IAiBlB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAwB7B;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;CAG1B"}
@@ -1,158 +0,0 @@
1
- /**
2
- * Compatibility Contracts — Migration Registry
3
- *
4
- * The MigrationRegistry holds all registered schema migration steps and
5
- * provides path resolution and ordered execution for any version pair.
6
- *
7
- * @module contracts/migrations
8
- */
9
- import { compareVersions, versionsEqual, versionToString, } from '../types.js';
10
- /**
11
- * Central registry for all schema migration steps.
12
- *
13
- * Migrations are registered per contract name and resolved as an ordered
14
- * chain from a given source version to the current target version.
15
- * All migration functions must be pure (no mutations, no side effects).
16
- */
17
- export class MigrationRegistry {
18
- steps = new Map();
19
- /**
20
- * Registers a migration step for a given contract.
21
- *
22
- * Steps are stored in insertion order and sorted at resolution time.
23
- * Duplicate from→to pairs for the same contract are not permitted.
24
- *
25
- * @param contract - The contract name (e.g. 'runtimeState').
26
- * @param step - The migration step to register.
27
- * @throws If a step with the same from→to is already registered.
28
- */
29
- register(contract, step) {
30
- if (!this.steps.has(contract)) {
31
- this.steps.set(contract, []);
32
- }
33
- const existing = this.steps.get(contract);
34
- const duplicate = existing.find((s) => versionsEqual(s.from, step.from) && versionsEqual(s.to, step.to));
35
- if (duplicate) {
36
- throw new Error(`Duplicate migration step for contract '${contract}': ` +
37
- `${versionToString(step.from)} → ${versionToString(step.to)}`);
38
- }
39
- existing.push(step);
40
- }
41
- /**
42
- * Returns true if any migration path exists from `fromVersion` toward
43
- * a higher version for the given contract.
44
- *
45
- * @param contract - The contract name.
46
- * @param fromVersion - The source schema version to migrate from.
47
- */
48
- canMigrate(contract, fromVersion) {
49
- const steps = this.steps.get(contract) ?? [];
50
- return steps.some((s) => versionsEqual(s.from, fromVersion));
51
- }
52
- /**
53
- * Resolves an ordered chain of migration steps from `from` to `to`.
54
- *
55
- * Uses a greedy forward walk: at each version, finds the step that advances
56
- * closest to the target. Throws if no complete path exists.
57
- *
58
- * @param contract - The contract name.
59
- * @param from - The starting schema version.
60
- * @param to - The target schema version.
61
- * @returns Ordered array of MigrationSteps forming the complete path.
62
- * @throws If no migration path exists between the two versions.
63
- */
64
- getMigrationPath(contract, from, to) {
65
- if (versionsEqual(from, to))
66
- return [];
67
- if (compareVersions(from, to) > 0) {
68
- throw new Error(`Downgrade migration is not supported for contract '${contract}': ` +
69
- `cannot migrate from ${versionToString(from)} to ${versionToString(to)}`);
70
- }
71
- const allSteps = this.steps.get(contract) ?? [];
72
- const path = [];
73
- let current = from;
74
- while (!versionsEqual(current, to)) {
75
- // Find all steps that start from the current version
76
- const candidates = allSteps.filter((s) => versionsEqual(s.from, current));
77
- if (candidates.length === 0) {
78
- throw new Error(`No migration step found for contract '${contract}' ` +
79
- `at version ${versionToString(current)} (target: ${versionToString(to)})`);
80
- }
81
- // Pick the step that advances closest to the target without overshooting
82
- const step = candidates.reduce((best, candidate) => {
83
- const cmpBest = compareVersions(best.to, to);
84
- const cmpCandidate = compareVersions(candidate.to, to);
85
- // Prefer steps that don't overshoot; among those, prefer the one closest to target
86
- if (cmpBest > 0 && cmpCandidate <= 0)
87
- return candidate;
88
- if (cmpCandidate > 0 && cmpBest <= 0)
89
- return best;
90
- return compareVersions(candidate.to, best.to) > 0 ? candidate : best;
91
- });
92
- if (compareVersions(step.to, current) <= 0) {
93
- throw new Error(`Migration step for contract '${contract}' does not advance version: ` +
94
- `${versionToString(step.from)} → ${versionToString(step.to)}`);
95
- }
96
- path.push(step);
97
- current = step.to;
98
- if (path.length > 100) {
99
- throw new Error(`Migration path for contract '${contract}' exceeded 100 steps — possible cycle detected`);
100
- }
101
- }
102
- return path;
103
- }
104
- /**
105
- * Migrates data from `fromVersion` to the latest version reachable via
106
- * registered steps for the given contract.
107
- *
108
- * If `fromVersion` already matches the end of the migration chain,
109
- * the data is returned as-is without transformation.
110
- *
111
- * @param contract - The contract name.
112
- * @param data - The raw data to migrate.
113
- * @param fromVersion - The schema version of the incoming data.
114
- * @returns The migrated data and the version it was migrated to.
115
- * @throws If the migration path is incomplete or a step throws.
116
- */
117
- migrate(contract, data, fromVersion) {
118
- // Find the highest reachable version from this starting point
119
- const targetVersion = this._resolveLatestVersion(contract, fromVersion);
120
- if (versionsEqual(fromVersion, targetVersion)) {
121
- return { data, version: fromVersion };
122
- }
123
- const path = this.getMigrationPath(contract, fromVersion, targetVersion);
124
- let current = data;
125
- for (const step of path) {
126
- current = step.migrate(current);
127
- }
128
- return { data: current, version: targetVersion };
129
- }
130
- /**
131
- * Resolves the highest version reachable from `fromVersion` by following
132
- * the chain of registered steps.
133
- */
134
- _resolveLatestVersion(contract, fromVersion) {
135
- const allSteps = this.steps.get(contract) ?? [];
136
- let current = fromVersion;
137
- const visited = new Set();
138
- while (true) {
139
- const key = versionToString(current);
140
- if (visited.has(key))
141
- break;
142
- visited.add(key);
143
- const next = allSteps
144
- .filter((s) => versionsEqual(s.from, current))
145
- .sort((a, b) => compareVersions(b.to, a.to))[0];
146
- if (!next)
147
- break;
148
- current = next.to;
149
- }
150
- return current;
151
- }
152
- /**
153
- * Returns all registered contract names.
154
- */
155
- contractNames() {
156
- return [...this.steps.keys()];
157
- }
158
- }
@@ -1,57 +0,0 @@
1
- /**
2
- * Compatibility Contracts — Consolidated Migration Schemas
3
- *
4
- * All domain migration steps in one place. Each schema section:
5
- * - Declares a private `_STEPS` array (MigrationStep[])
6
- * - Exports a `_VERSION` constant (re-exported from SCHEMA_VERSIONS)
7
- * - Exports a `get…MigrationSteps()` function for the contract registry
8
- *
9
- * Previously split across 5 stub files; consolidated here for DRY.
10
- * Split back out if any individual contract accumulates > 10 migration steps.
11
- *
12
- * All migration functions must be pure — no mutations, no side effects.
13
- *
14
- * @module contracts/migrations/schemas
15
- */
16
- import type { MigrationStep } from '../types.js';
17
- /** The current EventEnvelope schema version (re-exported for convenience). */
18
- export declare const EVENT_ENVELOPE_VERSION: {
19
- readonly major: 1;
20
- readonly minor: 1;
21
- readonly patch: 0;
22
- };
23
- /** Returns all EventEnvelope migration steps. Used by the contract registry. */
24
- export declare function getEventEnvelopeMigrationSteps(): MigrationStep[];
25
- /** The current PluginManifest schema version (re-exported for convenience). */
26
- export declare const PLUGIN_MANIFEST_VERSION: {
27
- readonly major: 1;
28
- readonly minor: 0;
29
- readonly patch: 0;
30
- };
31
- /** Returns all PluginManifest migration steps. Used by the contract registry. */
32
- export declare function getPluginManifestMigrationSteps(): MigrationStep[];
33
- /** The current RuntimeState schema version (re-exported for convenience). */
34
- export declare const RUNTIME_STATE_VERSION: {
35
- readonly major: 1;
36
- readonly minor: 0;
37
- readonly patch: 0;
38
- };
39
- /** Returns all RuntimeState migration steps. Used by the contract registry. */
40
- export declare function getRuntimeStateMigrationSteps(): MigrationStep[];
41
- /** The current Session schema version (re-exported for convenience). */
42
- export declare const SESSION_VERSION: {
43
- readonly major: 1;
44
- readonly minor: 0;
45
- readonly patch: 0;
46
- };
47
- /** Returns all Session migration steps. Used by the contract registry. */
48
- export declare function getSessionMigrationSteps(): MigrationStep[];
49
- /** The current TaskRecord schema version (re-exported for convenience). */
50
- export declare const TASK_RECORD_VERSION: {
51
- readonly major: 1;
52
- readonly minor: 0;
53
- readonly patch: 0;
54
- };
55
- /** Returns all TaskRecord migration steps. Used by the contract registry. */
56
- export declare function getTaskRecordMigrationSteps(): MigrationStep[];
57
- //# sourceMappingURL=schemas.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../../../../src/_internal/platform/runtime/contracts/migrations/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA2BjD,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB;;;;CAAgC,CAAC;AAEpE,gFAAgF;AAChF,wBAAgB,8BAA8B,IAAI,aAAa,EAAE,CAEhE;AA0BD,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB;;;;CAAiC,CAAC;AAEtE,iFAAiF;AACjF,wBAAgB,+BAA+B,IAAI,aAAa,EAAE,CAEjE;AA0BD,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB;;;;CAA+B,CAAC;AAElE,+EAA+E;AAC/E,wBAAgB,6BAA6B,IAAI,aAAa,EAAE,CAE/D;AA2BD,wEAAwE;AACxE,eAAO,MAAM,eAAe;;;;CAA0B,CAAC;AAEvD,0EAA0E;AAC1E,wBAAgB,wBAAwB,IAAI,aAAa,EAAE,CAE1D;AA0BD,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB;;;;CAA6B,CAAC;AAE9D,6EAA6E;AAC7E,wBAAgB,2BAA2B,IAAI,aAAa,EAAE,CAE7D"}