@altopelago/aeon-aes 0.12.0 → 0.12.1

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 (47) hide show
  1. package/README.md +19 -2
  2. package/dist/events.d.ts +5 -0
  3. package/dist/events.d.ts.map +1 -1
  4. package/dist/events.js +3 -0
  5. package/dist/events.js.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/modes.d.ts.map +1 -1
  11. package/dist/modes.js +14 -8
  12. package/dist/modes.js.map +1 -1
  13. package/dist/paths.d.ts +1 -0
  14. package/dist/paths.d.ts.map +1 -1
  15. package/dist/paths.js +33 -29
  16. package/dist/paths.js.map +1 -1
  17. package/dist/portable.d.ts +98 -0
  18. package/dist/portable.d.ts.map +1 -0
  19. package/dist/portable.js +524 -0
  20. package/dist/portable.js.map +1 -0
  21. package/dist/references.d.ts.map +1 -1
  22. package/dist/references.js +9 -4
  23. package/dist/references.js.map +1 -1
  24. package/dist/resolve.d.ts.map +1 -1
  25. package/dist/resolve.js +52 -2
  26. package/dist/resolve.js.map +1 -1
  27. package/dist/sha256.d.ts +3 -0
  28. package/dist/sha256.d.ts.map +1 -0
  29. package/dist/sha256.js +82 -0
  30. package/dist/sha256.js.map +1 -0
  31. package/dist/telex-datatype-internal.d.ts +12 -0
  32. package/dist/telex-datatype-internal.d.ts.map +1 -0
  33. package/dist/telex-datatype-internal.js +323 -0
  34. package/dist/telex-datatype-internal.js.map +1 -0
  35. package/dist/telex-internal.d.ts +60 -0
  36. package/dist/telex-internal.d.ts.map +1 -0
  37. package/dist/telex-internal.js +1101 -0
  38. package/dist/telex-internal.js.map +1 -0
  39. package/dist/telex-limits-internal.d.ts +35 -0
  40. package/dist/telex-limits-internal.d.ts.map +1 -0
  41. package/dist/telex-limits-internal.js +70 -0
  42. package/dist/telex-limits-internal.js.map +1 -0
  43. package/dist/telex.d.ts +128 -0
  44. package/dist/telex.d.ts.map +1 -0
  45. package/dist/telex.js +46 -0
  46. package/dist/telex.js.map +1 -0
  47. package/package.json +3 -3
@@ -0,0 +1,98 @@
1
+ import type { AssignmentEvent } from './events.js';
2
+ import { type AesDatatypeDescriptor, type AesNumberLiteral, type AesStringLiteral } from './telex.js';
3
+ export type PortableAesKind = 'StringLiteral' | 'NumberLiteral' | 'InfinityLiteral' | 'NaNLiteral' | 'NullLiteral' | 'BooleanLiteral' | 'ToggleLiteral' | 'HexLiteral' | 'RadixLiteral' | 'EncodingLiteral' | 'SeparatorLiteral' | 'SansaAddressLiteral' | 'DateLiteral' | 'TimeLiteral' | 'DateTimeLiteral' | 'WTCDateTimeLiteral' | 'ObjectNode' | 'ListNode' | 'TupleLiteral' | 'NodeLiteral' | 'NodeHead' | 'CloneReference' | 'PointerReference';
4
+ /**
5
+ * Encoding-neutral AES event shape used by the portable projection work.
6
+ */
7
+ export interface PortableAesEvent {
8
+ readonly path: string;
9
+ readonly kind: PortableAesKind;
10
+ readonly identity?: string;
11
+ readonly datatype?: string;
12
+ readonly generics?: readonly (AesDatatypeDescriptor | AesNumberLiteral)[];
13
+ readonly clarifiers?: readonly (AesStringLiteral | AesNumberLiteral)[];
14
+ readonly value?: string;
15
+ readonly origin?: string;
16
+ readonly span?: string;
17
+ }
18
+ export declare const TYPESCRIPT_ASSIGNMENT_EVENTS_CONTRACT_V0: 'aeon.typescript.assignment-events.v0';
19
+ export declare const TYPESCRIPT_PORTABLE_AES_ADAPTER_V0: 'aeon.typescript.assignment-events.v0-to-aes.events.v1';
20
+ export declare const TYPESCRIPT_PORTABLE_AES_ADAPTER_VERSION_V1: '1.0.0';
21
+ export type PortableAesConversionChangeKind = 'transformed' | 'synthesized' | 'omitted' | 'semantic-loss';
22
+ export interface PortableAesConversionChange {
23
+ readonly kind: PortableAesConversionChangeKind;
24
+ readonly code: string;
25
+ readonly field: string;
26
+ readonly message: string;
27
+ readonly sourcePath?: string;
28
+ readonly targetPath?: string;
29
+ readonly requiresAuthorization: boolean;
30
+ }
31
+ export interface PortableAesConversionReportV1 {
32
+ readonly sourceContract: typeof TYPESCRIPT_ASSIGNMENT_EVENTS_CONTRACT_V0;
33
+ readonly targetContract: 'aes.events.v1';
34
+ readonly adapter: typeof TYPESCRIPT_PORTABLE_AES_ADAPTER_V0;
35
+ readonly adapterVersion: typeof TYPESCRIPT_PORTABLE_AES_ADAPTER_VERSION_V1;
36
+ readonly profile: 'aes.complete.v1';
37
+ readonly projection: null | 'aeon.document.v1';
38
+ readonly semanticLossless: boolean;
39
+ readonly recordLossless: boolean;
40
+ readonly provenanceLossless: boolean;
41
+ readonly semanticLossAuthorized: boolean;
42
+ readonly changes: readonly PortableAesConversionChange[];
43
+ }
44
+ export interface PortableAesCompatibilityEvent extends Omit<PortableAesEvent, 'path'> {
45
+ readonly path?: string;
46
+ readonly header?: string;
47
+ }
48
+ export interface PortableAesCompatibilityResultV1 {
49
+ readonly events: readonly PortableAesCompatibilityEvent[];
50
+ readonly report: PortableAesConversionReportV1;
51
+ }
52
+ export interface PortableAesCompatibilityOptions {
53
+ readonly includeHeaders?: boolean;
54
+ /** Exact unprefixed fields from the retained AEON header model. */
55
+ readonly headerFieldNames?: readonly string[] | ReadonlySet<string>;
56
+ /** Exact, unnormalized UTF-8 source artifact used to derive origin and byte spans. */
57
+ readonly sourceBytes?: Uint8Array;
58
+ }
59
+ export interface PortableAesProjectionOptions {
60
+ /** Exact unprefixed fields from the retained AEON header model. */
61
+ readonly headerFieldNames?: readonly string[] | ReadonlySet<string>;
62
+ }
63
+ export declare class PortableAesSourceError extends Error {
64
+ readonly code: string;
65
+ constructor(code: string, message: string);
66
+ }
67
+ /**
68
+ * Named, report-bearing compatibility adapter for the serialized TypeScript
69
+ * assignment-event contract. Existing projection helpers remain unchanged for
70
+ * same-process callers. Native spans are UTF-16 string indexes. They are
71
+ * omitted unless exact sourceBytes are supplied, in which case this boundary
72
+ * derives the source digest and converts scalar-aligned positions to UTF-8
73
+ * byte offsets.
74
+ */
75
+ export declare function adaptTypeScriptAssignmentEventsToPortableAes(events: readonly AssignmentEvent[], options?: PortableAesCompatibilityOptions): PortableAesCompatibilityResultV1;
76
+ /**
77
+ * Project legacy TypeScript AssignmentEvents into the portable flat shape.
78
+ *
79
+ * Every NodeLiteral becomes a value-less `NodeLiteral` event followed by one
80
+ * synthetic `NodeHead` event. Source child paths gain the NodeHead index,
81
+ * recursively, while ordinary member/list/tuple paths remain unchanged.
82
+ * Binding, anonymous-head, and node-head attributes are emitted as ordinary
83
+ * events beneath their owning path's `.@` address space. The default portable
84
+ * projection is body-only; use the named compatibility adapter with
85
+ * `includeHeaders: true` to select the explicit document projection.
86
+ */
87
+ export declare function projectPortableEvents(events: readonly AssignmentEvent[], options?: PortableAesProjectionOptions): readonly PortableAesEvent[];
88
+ /**
89
+ * Map native AssignmentEvent paths to their portable AES occurrence paths.
90
+ *
91
+ * The map is structure-aware: every indexed source segment beneath a node
92
+ * gains the synthetic NodeHead index. Synthetic NodeHead paths themselves do
93
+ * not have a native AssignmentEvent counterpart and are therefore absent.
94
+ */
95
+ export declare function createPortableEventPathMap(events: readonly AssignmentEvent[]): ReadonlyMap<string, string>;
96
+ /** Compatibility name retained while downstream callers adopt the complete projection name. */
97
+ export declare const projectPortableNodeEvents: typeof projectPortableEvents;
98
+ //# sourceMappingURL=portable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../src/portable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,524 @@
1
+ import { formatDatatypeAnnotation } from './datatype.js';
2
+ import { formatPath } from './paths.js';
3
+ import { sha256Hex } from './sha256.js';
4
+ import { parseDatatypeDescriptor, } from './telex.js';
5
+ export const TYPESCRIPT_ASSIGNMENT_EVENTS_CONTRACT_V0 = 'aeon.typescript.assignment-events.v0';
6
+ export const TYPESCRIPT_PORTABLE_AES_ADAPTER_V0 = 'aeon.typescript.assignment-events.v0-to-aes.events.v1';
7
+ export const TYPESCRIPT_PORTABLE_AES_ADAPTER_VERSION_V1 = '1.0.0';
8
+ export class PortableAesSourceError extends Error {
9
+ code;
10
+ constructor(code, message) {
11
+ super(message);
12
+ this.name = 'PortableAesSourceError';
13
+ this.code = code;
14
+ }
15
+ }
16
+ /**
17
+ * Named, report-bearing compatibility adapter for the serialized TypeScript
18
+ * assignment-event contract. Existing projection helpers remain unchanged for
19
+ * same-process callers. Native spans are UTF-16 string indexes. They are
20
+ * omitted unless exact sourceBytes are supplied, in which case this boundary
21
+ * derives the source digest and converts scalar-aligned positions to UTF-8
22
+ * byte offsets.
23
+ */
24
+ export function adaptTypeScriptAssignmentEventsToPortableAes(events, options = {}) {
25
+ const includeHeaders = options.includeHeaders === true;
26
+ const headerFieldNames = options.headerFieldNames === undefined
27
+ ? undefined
28
+ : new Set(options.headerFieldNames);
29
+ const isHeader = (event) => isLegacyHeaderEvent(event, headerFieldNames);
30
+ const body = events.filter((event) => !isHeader(event));
31
+ const headers = includeHeaders ? events.filter(isHeader) : [];
32
+ const provenance = options.sourceBytes === undefined ? null : createPortableSourceContext(options.sourceBytes);
33
+ const bodyEvents = projectPortableEventsWithLocalSpans(body)
34
+ .map((event) => applyPortableProvenance(event, provenance));
35
+ const headerEvents = projectPortableEventsWithLocalSpans(headers).map((local) => {
36
+ const event = applyPortableProvenance(local, provenance);
37
+ const { path, span: _span, ...rest } = event;
38
+ if (path === undefined) {
39
+ throw new PortableAesSourceError('AES_COMPAT_HEADER_PATH_MISSING', 'A projected legacy header event must retain its source path.');
40
+ }
41
+ return { header: path, ...rest, ...(event.span !== undefined ? { span: event.span } : {}) };
42
+ });
43
+ const projected = [...headerEvents, ...bodyEvents];
44
+ const changes = compatibilityChanges(events, body, projected, includeHeaders, provenance !== null, headerFieldNames);
45
+ const provenanceLossless = events.length === 0 || (provenance !== null
46
+ && projected.length > 0
47
+ && projected.every((event) => event.origin !== undefined && event.span !== undefined));
48
+ return {
49
+ events: projected,
50
+ report: {
51
+ sourceContract: TYPESCRIPT_ASSIGNMENT_EVENTS_CONTRACT_V0,
52
+ targetContract: 'aes.events.v1',
53
+ adapter: TYPESCRIPT_PORTABLE_AES_ADAPTER_V0,
54
+ adapterVersion: TYPESCRIPT_PORTABLE_AES_ADAPTER_VERSION_V1,
55
+ profile: 'aes.complete.v1',
56
+ projection: includeHeaders ? 'aeon.document.v1' : null,
57
+ semanticLossless: true,
58
+ recordLossless: events.length === 0,
59
+ provenanceLossless,
60
+ semanticLossAuthorized: false,
61
+ changes,
62
+ },
63
+ };
64
+ }
65
+ /**
66
+ * Project legacy TypeScript AssignmentEvents into the portable flat shape.
67
+ *
68
+ * Every NodeLiteral becomes a value-less `NodeLiteral` event followed by one
69
+ * synthetic `NodeHead` event. Source child paths gain the NodeHead index,
70
+ * recursively, while ordinary member/list/tuple paths remain unchanged.
71
+ * Binding, anonymous-head, and node-head attributes are emitted as ordinary
72
+ * events beneath their owning path's `.@` address space. The default portable
73
+ * projection is body-only; use the named compatibility adapter with
74
+ * `includeHeaders: true` to select the explicit document projection.
75
+ */
76
+ export function projectPortableEvents(events, options = {}) {
77
+ const headerFieldNames = options.headerFieldNames === undefined
78
+ ? undefined
79
+ : new Set(options.headerFieldNames);
80
+ return projectPortableEventsWithLocalSpans(events.filter((event) => !isLegacyHeaderEvent(event, headerFieldNames)))
81
+ .map((projected) => projected.event);
82
+ }
83
+ function projectPortableEventsWithLocalSpans(events) {
84
+ const nodeSourcePaths = new Set(events
85
+ .filter((event) => unwrapTypedValue(event.value).type === 'NodeLiteral')
86
+ .map((event) => formatPath(event.path)));
87
+ const projected = [];
88
+ for (const event of events) {
89
+ const translatedPath = translateNodePath(event.path, nodeSourcePaths);
90
+ const translatedPathText = formatPath(translatedPath);
91
+ const value = unwrapTypedValue(event.value);
92
+ pushProjected(projected, projectEvent(event, translatedPath, value, nodeSourcePaths), event.span);
93
+ projectMappedAttributes(event.annotations, translatedPathText, projected, nodeSourcePaths);
94
+ if (value.type === 'NodeLiteral') {
95
+ const headPath = `${translatedPathText}[0]`;
96
+ pushProjected(projected, {
97
+ path: headPath,
98
+ kind: 'NodeHead',
99
+ ...(value.structuralId !== null ? { identity: value.structuralId } : {}),
100
+ ...projectDatatype(value.datatype === null ? undefined : formatDatatypeAnnotation(value.datatype)),
101
+ value: value.tag,
102
+ }, value.headSpan);
103
+ projectParserAttributes(value.attributes, headPath, projected, nodeSourcePaths);
104
+ }
105
+ }
106
+ return projected;
107
+ }
108
+ /**
109
+ * Map native AssignmentEvent paths to their portable AES occurrence paths.
110
+ *
111
+ * The map is structure-aware: every indexed source segment beneath a node
112
+ * gains the synthetic NodeHead index. Synthetic NodeHead paths themselves do
113
+ * not have a native AssignmentEvent counterpart and are therefore absent.
114
+ */
115
+ export function createPortableEventPathMap(events) {
116
+ const nodeSourcePaths = new Set(events
117
+ .filter((event) => unwrapTypedValue(event.value).type === 'NodeLiteral')
118
+ .map((event) => formatPath(event.path)));
119
+ return new Map(events.map((event) => [
120
+ formatPath(event.path),
121
+ formatPath(translateNodePath(event.path, nodeSourcePaths)),
122
+ ]));
123
+ }
124
+ /** Compatibility name retained while downstream callers adopt the complete projection name. */
125
+ export const projectPortableNodeEvents = projectPortableEvents;
126
+ function projectMappedAttributes(attributes, ownerPath, projected, nodeSourcePaths) {
127
+ if (!attributes)
128
+ return;
129
+ for (const [key, entry] of attributes) {
130
+ projectValueTree(appendAttribute(ownerPath, key), entry.value, {
131
+ ...(entry.structuralId != null ? { identity: entry.structuralId } : {}),
132
+ ...(entry.datatype !== undefined ? { datatype: entry.datatype } : {}),
133
+ ...(entry.annotations !== undefined ? { mappedAttributes: entry.annotations } : {}),
134
+ ...(entry.span !== undefined ? { sourceSpan: entry.span } : {}),
135
+ }, projected, nodeSourcePaths);
136
+ }
137
+ }
138
+ function projectParserAttributes(attributes, ownerPath, projected, nodeSourcePaths) {
139
+ for (const attribute of attributes) {
140
+ for (const [key, entry] of attribute.entries) {
141
+ projectValueTree(appendAttribute(ownerPath, key), entry.value, {
142
+ ...(entry.structuralId !== null ? { identity: entry.structuralId } : {}),
143
+ ...(entry.datatype !== null ? { datatype: formatDatatypeAnnotation(entry.datatype) } : {}),
144
+ parserAttributes: entry.attributes,
145
+ ...(entry.span !== undefined ? { sourceSpan: entry.span } : {}),
146
+ }, projected, nodeSourcePaths);
147
+ }
148
+ }
149
+ }
150
+ function projectValueTree(path, rawValue, metadata, projected, nodeSourcePaths) {
151
+ const value = unwrapTypedValue(rawValue);
152
+ const portableValue = projectValue(value, nodeSourcePaths);
153
+ pushProjected(projected, {
154
+ path,
155
+ kind: portableValue.kind,
156
+ ...(metadata.identity !== undefined ? { identity: metadata.identity } : {}),
157
+ ...projectDatatype(metadata.datatype),
158
+ ...(portableValue.value !== undefined ? { value: portableValue.value } : {}),
159
+ }, metadata.sourceSpan ?? rawValue.span);
160
+ projectMappedAttributes(metadata.mappedAttributes, path, projected, nodeSourcePaths);
161
+ projectParserAttributes(metadata.parserAttributes ?? [], path, projected, nodeSourcePaths);
162
+ switch (value.type) {
163
+ case 'ObjectNode':
164
+ for (const binding of value.bindings) {
165
+ projectBindingTree(appendMember(path, binding.key), binding, projected, nodeSourcePaths);
166
+ }
167
+ return;
168
+ case 'ListNode':
169
+ case 'TupleLiteral':
170
+ for (let index = 0; index < value.elements.length; index += 1) {
171
+ projectAnonymousTree(`${path}[${index}]`, value.elements[index], projected, nodeSourcePaths);
172
+ }
173
+ return;
174
+ case 'NodeLiteral': {
175
+ const headPath = `${path}[0]`;
176
+ pushProjected(projected, {
177
+ path: headPath,
178
+ kind: 'NodeHead',
179
+ ...(value.structuralId !== null ? { identity: value.structuralId } : {}),
180
+ ...projectDatatype(value.datatype === null ? undefined : formatDatatypeAnnotation(value.datatype)),
181
+ value: value.tag,
182
+ }, value.headSpan);
183
+ projectParserAttributes(value.attributes, headPath, projected, nodeSourcePaths);
184
+ for (let index = 0; index < value.children.length; index += 1) {
185
+ projectAnonymousTree(`${headPath}[${index}]`, value.children[index], projected, nodeSourcePaths);
186
+ }
187
+ return;
188
+ }
189
+ default:
190
+ return;
191
+ }
192
+ }
193
+ function projectBindingTree(path, binding, projected, nodeSourcePaths) {
194
+ projectValueTree(path, binding.value, {
195
+ ...(binding.structuralId !== null ? { identity: binding.structuralId } : {}),
196
+ ...(binding.datatype !== null ? { datatype: formatDatatypeAnnotation(binding.datatype) } : {}),
197
+ parserAttributes: binding.attributes,
198
+ sourceSpan: binding.span,
199
+ }, projected, nodeSourcePaths);
200
+ }
201
+ function projectAnonymousTree(path, rawValue, projected, nodeSourcePaths) {
202
+ if (rawValue.type !== 'TypedValue') {
203
+ projectValueTree(path, rawValue, { sourceSpan: rawValue.span }, projected, nodeSourcePaths);
204
+ return;
205
+ }
206
+ projectValueTree(path, rawValue.value, {
207
+ ...(rawValue.structuralId !== null ? { identity: rawValue.structuralId } : {}),
208
+ ...(rawValue.datatype !== null ? { datatype: formatDatatypeAnnotation(rawValue.datatype) } : {}),
209
+ parserAttributes: rawValue.attributes,
210
+ sourceSpan: rawValue.span,
211
+ }, projected, nodeSourcePaths);
212
+ }
213
+ function appendMember(ownerPath, key) {
214
+ return `${ownerPath}${formatPath({ segments: [{ type: 'root' }, { type: 'member', key }] }).slice(1)}`;
215
+ }
216
+ function appendAttribute(ownerPath, key) {
217
+ return `${ownerPath}.@${formatPath({ segments: [{ type: 'root' }, { type: 'member', key }] }).slice(1)}`;
218
+ }
219
+ function translateNodePath(path, nodeSourcePaths) {
220
+ const sourceSegments = [];
221
+ const targetSegments = [];
222
+ for (const segment of path.segments) {
223
+ if (segment.type === 'index'
224
+ && sourceSegments.length > 0
225
+ && nodeSourcePaths.has(formatPath({ segments: sourceSegments }))) {
226
+ targetSegments.push({ type: 'index', index: 0 });
227
+ }
228
+ sourceSegments.push(segment);
229
+ targetSegments.push(segment);
230
+ }
231
+ return { segments: targetSegments };
232
+ }
233
+ function projectEvent(event, path, value, nodeSourcePaths) {
234
+ const projectedValue = projectValue(value, nodeSourcePaths);
235
+ return {
236
+ path: formatPath(path),
237
+ kind: projectedValue.kind,
238
+ ...(event.structuralId != null ? { identity: event.structuralId } : {}),
239
+ ...projectDatatype(event.datatype),
240
+ ...(projectedValue.value !== undefined ? { value: projectedValue.value } : {}),
241
+ };
242
+ }
243
+ function projectDatatype(datatype) {
244
+ if (datatype === undefined)
245
+ return {};
246
+ const descriptor = parseDatatypeDescriptor(datatype);
247
+ return {
248
+ datatype: descriptor.datatype,
249
+ generics: descriptor.generics,
250
+ clarifiers: descriptor.clarifiers,
251
+ };
252
+ }
253
+ function projectValue(value, nodeSourcePaths) {
254
+ switch (value.type) {
255
+ case 'TypedValue':
256
+ return projectValue(value.value, nodeSourcePaths);
257
+ case 'StringLiteral':
258
+ return { kind: 'StringLiteral', value: value.value };
259
+ case 'NumberLiteral':
260
+ return { kind: 'NumberLiteral', value: value.value };
261
+ case 'InfinityLiteral':
262
+ return { kind: 'InfinityLiteral', value: value.value };
263
+ case 'NaNLiteral':
264
+ return { kind: 'NaNLiteral', value: value.value };
265
+ case 'NullLiteral':
266
+ return { kind: 'NullLiteral', value: value.value };
267
+ case 'BooleanLiteral':
268
+ return { kind: 'BooleanLiteral', value: String(value.value) };
269
+ case 'ToggleLiteral':
270
+ return { kind: 'ToggleLiteral', value: value.value };
271
+ case 'HexLiteral':
272
+ return { kind: 'HexLiteral', value: value.value };
273
+ case 'RadixLiteral':
274
+ return { kind: 'RadixLiteral', value: value.value };
275
+ case 'EncodingLiteral':
276
+ return { kind: 'EncodingLiteral', value: value.value };
277
+ case 'SeparatorLiteral':
278
+ return { kind: 'SeparatorLiteral', value: value.value };
279
+ case 'SansaAddressLiteral':
280
+ return { kind: 'SansaAddressLiteral', value: value.canonical };
281
+ case 'DateLiteral':
282
+ return { kind: 'DateLiteral', value: value.value };
283
+ case 'TimeLiteral':
284
+ return { kind: 'TimeLiteral', value: value.value };
285
+ case 'DateTimeLiteral':
286
+ return { kind: value.raw.includes('&') ? 'WTCDateTimeLiteral' : 'DateTimeLiteral', value: value.value };
287
+ case 'ObjectNode':
288
+ return { kind: 'ObjectNode' };
289
+ case 'ListNode':
290
+ return { kind: 'ListNode' };
291
+ case 'TupleLiteral':
292
+ return { kind: 'TupleLiteral' };
293
+ case 'NodeLiteral':
294
+ return { kind: 'NodeLiteral' };
295
+ case 'CloneReference':
296
+ return { kind: 'CloneReference', value: translateReferenceTarget(value.path, nodeSourcePaths) };
297
+ case 'PointerReference':
298
+ return { kind: 'PointerReference', value: translateReferenceTarget(value.path, nodeSourcePaths) };
299
+ }
300
+ }
301
+ function translateReferenceTarget(segments, nodeSourcePaths) {
302
+ const sourceSegments = [{ type: 'root' }];
303
+ let sourcePathIsTrackable = true;
304
+ let out = '$';
305
+ for (const segment of segments) {
306
+ if (typeof segment === 'number') {
307
+ if (sourcePathIsTrackable && nodeSourcePaths.has(formatPath({ segments: sourceSegments }))) {
308
+ out += '[0]';
309
+ }
310
+ out += `[${segment}]`;
311
+ if (sourcePathIsTrackable)
312
+ sourceSegments.push({ type: 'index', index: segment });
313
+ continue;
314
+ }
315
+ const key = typeof segment === 'string' ? segment : segment.key;
316
+ const member = formatPath({ segments: [{ type: 'root' }, { type: 'member', key }] }).slice(1);
317
+ if (typeof segment === 'string') {
318
+ out += member;
319
+ if (sourcePathIsTrackable)
320
+ sourceSegments.push({ type: 'member', key: segment });
321
+ }
322
+ else {
323
+ out += `.@${member}`;
324
+ sourcePathIsTrackable = false;
325
+ }
326
+ }
327
+ return out;
328
+ }
329
+ function isLegacyHeaderEvent(event, headerFieldNames) {
330
+ if (event.sourcePlane !== undefined)
331
+ return event.sourcePlane === 'header';
332
+ const segment = event.path.segments[1];
333
+ if (segment?.type !== 'member' || !segment.key.startsWith('aeon:'))
334
+ return false;
335
+ return headerFieldNames === undefined || headerFieldNames.has(segment.key.slice('aeon:'.length));
336
+ }
337
+ function compatibilityChanges(sourceEvents, bodyEvents, projected, includeHeaders, sourceBacked, headerFieldNames) {
338
+ const changes = [];
339
+ const pathMap = createPortableEventPathMap(bodyEvents);
340
+ for (const event of sourceEvents) {
341
+ const sourcePath = formatPath(event.path);
342
+ const header = isLegacyHeaderEvent(event, headerFieldNames);
343
+ const targetPath = header && includeHeaders ? sourcePath : pathMap.get(sourcePath);
344
+ if (!sourceBacked) {
345
+ changes.push({
346
+ kind: 'omitted',
347
+ code: 'AES_COMPAT_PROVENANCE_OMITTED',
348
+ field: 'span',
349
+ message: 'The local source span is omitted because it is not bound to an immutable portable origin.',
350
+ sourcePath,
351
+ ...(targetPath !== undefined ? { targetPath } : {}),
352
+ requiresAuthorization: false,
353
+ });
354
+ }
355
+ changes.push({
356
+ kind: 'transformed',
357
+ code: 'AES_COMPAT_SOURCE_REPRESENTATION_REDUCED',
358
+ field: 'key,normalizedPath,value',
359
+ message: 'Implementation-specific navigation fields and AST representation are reduced to portable AES fields.',
360
+ sourcePath,
361
+ ...(targetPath !== undefined ? { targetPath } : {}),
362
+ requiresAuthorization: false,
363
+ });
364
+ if (header && !includeHeaders) {
365
+ changes.push({
366
+ kind: 'omitted',
367
+ code: 'AES_COMPAT_HEADER_EXCLUDED',
368
+ field: 'event',
369
+ message: 'The synthetic AEON header event is excluded by the default body-only projection.',
370
+ sourcePath,
371
+ requiresAuthorization: false,
372
+ });
373
+ continue;
374
+ }
375
+ if (header) {
376
+ changes.push({
377
+ kind: 'transformed',
378
+ code: 'AES_COMPAT_HEADER_PROJECTED',
379
+ field: 'path',
380
+ message: 'The recognized synthetic AEON header event is moved to the header address plane.',
381
+ sourcePath,
382
+ targetPath: sourcePath,
383
+ requiresAuthorization: false,
384
+ });
385
+ }
386
+ else if (targetPath !== undefined && targetPath !== sourcePath) {
387
+ changes.push({
388
+ kind: 'transformed',
389
+ code: 'AES_COMPAT_PATH_TRANSLATED',
390
+ field: 'path',
391
+ message: 'The source occurrence path is translated through the explicit portable node-head level.',
392
+ sourcePath,
393
+ targetPath,
394
+ requiresAuthorization: false,
395
+ });
396
+ }
397
+ const value = unwrapTypedValue(event.value);
398
+ if (value.type === 'CloneReference' || value.type === 'PointerReference') {
399
+ const sourceTarget = translateReferenceTarget(value.path, new Set());
400
+ const nodePaths = new Set(bodyEvents
401
+ .filter((candidate) => unwrapTypedValue(candidate.value).type === 'NodeLiteral')
402
+ .map((candidate) => formatPath(candidate.path)));
403
+ const portableTarget = translateReferenceTarget(value.path, nodePaths);
404
+ if (sourceTarget !== portableTarget) {
405
+ changes.push({
406
+ kind: 'transformed',
407
+ code: 'AES_COMPAT_REFERENCE_TRANSLATED',
408
+ field: 'value.path',
409
+ message: `The reference target is translated from ${sourceTarget} to ${portableTarget}.`,
410
+ sourcePath,
411
+ ...(targetPath !== undefined ? { targetPath } : {}),
412
+ requiresAuthorization: false,
413
+ });
414
+ }
415
+ }
416
+ }
417
+ for (const event of projected) {
418
+ const targetPath = event.path ?? event.header;
419
+ if (sourceBacked) {
420
+ changes.push(event.span === undefined ? {
421
+ kind: 'omitted',
422
+ code: 'AES_COMPAT_PROVENANCE_RANGE_OMITTED',
423
+ field: 'span',
424
+ message: 'The exact source is identified, but this occurrence has no independently retained source range.',
425
+ ...(targetPath !== undefined ? { targetPath } : {}),
426
+ requiresAuthorization: false,
427
+ } : {
428
+ kind: 'transformed',
429
+ code: 'AES_COMPAT_UTF8_SPAN_CONVERTED',
430
+ field: 'span',
431
+ message: 'The native UTF-16 source range is converted to an exact UTF-8 byte range.',
432
+ ...(targetPath !== undefined ? { targetPath } : {}),
433
+ requiresAuthorization: false,
434
+ });
435
+ }
436
+ if (event.kind === 'NodeHead') {
437
+ changes.push({
438
+ kind: 'synthesized',
439
+ code: 'AES_COMPAT_NODE_HEAD_SYNTHESIZED',
440
+ field: 'NodeHead',
441
+ message: 'The implicit implementation node tag is emitted as an explicit portable NodeHead event.',
442
+ ...(targetPath !== undefined ? { targetPath } : {}),
443
+ requiresAuthorization: false,
444
+ });
445
+ }
446
+ if (targetPath?.includes('.@')) {
447
+ changes.push({
448
+ kind: 'transformed',
449
+ code: 'AES_COMPAT_ATTRIBUTE_FLATTENED',
450
+ field: 'attributes',
451
+ message: 'The nested implementation attribute entry is emitted as an ordinary flat AES event.',
452
+ targetPath,
453
+ requiresAuthorization: false,
454
+ });
455
+ }
456
+ if (event.datatype !== undefined) {
457
+ changes.push({
458
+ kind: 'transformed',
459
+ code: 'AES_COMPAT_DATATYPE_EXPANDED',
460
+ field: 'datatype',
461
+ message: 'The combined datatype descriptor is expanded into datatype, generics, and clarifiers.',
462
+ ...(targetPath !== undefined ? { targetPath } : {}),
463
+ requiresAuthorization: false,
464
+ });
465
+ }
466
+ }
467
+ return changes;
468
+ }
469
+ function createPortableSourceContext(sourceBytes) {
470
+ if (!(sourceBytes instanceof Uint8Array)) {
471
+ throw new PortableAesSourceError('AES_COMPAT_SOURCE_REQUIRED', 'Portable source provenance requires exact UTF-8 bytes.');
472
+ }
473
+ const bytes = Uint8Array.from(sourceBytes);
474
+ let source;
475
+ try {
476
+ source = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
477
+ }
478
+ catch {
479
+ throw new PortableAesSourceError('AES_SOURCE_INVALID_UTF8', 'Portable source provenance requires a valid UTF-8 artifact.');
480
+ }
481
+ const byteOffsets = new Array(source.length + 1).fill(null);
482
+ let utf16Offset = 0;
483
+ let byteOffset = 0;
484
+ byteOffsets[0] = 0;
485
+ while (utf16Offset < source.length) {
486
+ const codePoint = source.codePointAt(utf16Offset);
487
+ const codeUnitWidth = codePoint > 0xFFFF ? 2 : 1;
488
+ byteOffset += utf8CodePointWidth(codePoint);
489
+ utf16Offset += codeUnitWidth;
490
+ byteOffsets[utf16Offset] = byteOffset;
491
+ }
492
+ return {
493
+ origin: `sha256:${sha256Hex(bytes)}`,
494
+ byteOffsets,
495
+ };
496
+ }
497
+ function utf8CodePointWidth(codePoint) {
498
+ if (codePoint <= 0x7F)
499
+ return 1;
500
+ if (codePoint <= 0x7FF)
501
+ return 2;
502
+ if (codePoint <= 0xFFFF)
503
+ return 3;
504
+ return 4;
505
+ }
506
+ function applyPortableProvenance(projected, source) {
507
+ if (source === null)
508
+ return projected.event;
509
+ if (projected.sourceSpan === undefined)
510
+ return { ...projected.event, origin: source.origin };
511
+ const start = source.byteOffsets[projected.sourceSpan.start.offset];
512
+ const end = source.byteOffsets[projected.sourceSpan.end.offset];
513
+ if (start === undefined || end === undefined || start === null || end === null || start >= end) {
514
+ throw new PortableAesSourceError('AES_COMPAT_SOURCE_RANGE_INVALID', `Native source span ${projected.sourceSpan.start.offset}:${projected.sourceSpan.end.offset} is outside the exact UTF-8 artifact or splits a Unicode scalar.`);
515
+ }
516
+ return { ...projected.event, origin: source.origin, span: `${start}:${end}` };
517
+ }
518
+ function pushProjected(projected, event, sourceSpan) {
519
+ projected.push({ event, ...(sourceSpan !== undefined ? { sourceSpan } : {}) });
520
+ }
521
+ function unwrapTypedValue(value) {
522
+ return value.type === 'TypedValue' ? unwrapTypedValue(value.value) : value;
523
+ }
524
+ //# sourceMappingURL=portable.js.map