@shapeshift-labs/frontier-lang-compiler 0.2.84 → 0.2.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -933,7 +933,6 @@ The published Frontier package family is generated from one shared package catal
933
933
  - [`@shapeshift-labs/frontier-realtime-server`](https://www.npmjs.com/package/@shapeshift-labs/frontier-realtime-server): Authoritative realtime room, tick, command validation, rate-limit, session, and snapshot-history runtime.
934
934
  - [`@shapeshift-labs/frontier-realtime-websocket`](https://www.npmjs.com/package/@shapeshift-labs/frontier-realtime-websocket): WebSocket client, wire, and Node room-server transport for Frontier realtime.
935
935
  - [`@shapeshift-labs/frontier-game`](https://www.npmjs.com/package/@shapeshift-labs/frontier-game): Game-facing entity, component, player, room, ownership, spatial interest, rollback, physics, and replication helpers above realtime.
936
- - [`@shapeshift-labs/loom`](https://www.npmjs.com/package/@shapeshift-labs/loom): Repo-level semantic collaboration CLI for .loom workspaces, including init, scan, status, graph snapshots, projection plans, Frontier Lang delegation, Frontier Swarm delegation, and Frontier Framework delegation.
937
936
 
938
937
  Package source repositories:
939
938
 
@@ -1027,4 +1026,3 @@ Package source repositories:
1027
1026
  - [`siliconjungle/-shapeshift-labs-frontier-realtime-server`](https://github.com/siliconjungle/-shapeshift-labs-frontier-realtime-server)
1028
1027
  - [`siliconjungle/-shapeshift-labs-frontier-realtime-websocket`](https://github.com/siliconjungle/-shapeshift-labs-frontier-realtime-websocket)
1029
1028
  - [`siliconjungle/-shapeshift-labs-frontier-game`](https://github.com/siliconjungle/-shapeshift-labs-frontier-game)
1030
- - [`siliconjungle/-shapeshift-labs-loom`](https://github.com/siliconjungle/-shapeshift-labs-loom)
@@ -40,6 +40,10 @@ export interface SemanticEditScriptOperation {
40
40
  readonly symbolKind?: string;
41
41
  readonly sourceSpan?: SourceSpan;
42
42
  };
43
+ readonly semanticKey?: string;
44
+ readonly semanticIdentityHash?: string;
45
+ readonly sourceIdentityHash?: string;
46
+ readonly operationContentHash?: string;
43
47
  readonly spans?: {
44
48
  readonly base?: SourceSpan;
45
49
  readonly worker?: SourceSpan;
@@ -84,6 +88,10 @@ export interface SemanticEditScriptSummary {
84
88
  readonly blocked: number;
85
89
  readonly candidates: number;
86
90
  readonly autoMergeCandidates: number;
91
+ readonly semanticKeys?: readonly string[];
92
+ readonly semanticIdentityHashes?: readonly string[];
93
+ readonly sourceIdentityHashes?: readonly string[];
94
+ readonly operationContentHashes?: readonly string[];
87
95
  }
88
96
 
89
97
  export interface SemanticEditScriptAdmission {
@@ -136,6 +144,7 @@ export interface SemanticEditProjectionEdit {
136
144
  readonly semanticKey?: string;
137
145
  readonly semanticIdentityHash?: string;
138
146
  readonly sourceIdentityHash?: string;
147
+ readonly operationContentHash?: string;
139
148
  readonly editContentHash?: string;
140
149
  readonly headStart: number;
141
150
  readonly headEnd: number;
@@ -1,5 +1,6 @@
1
1
  import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
2
  import { idFragment, uniqueStrings } from '../../native-import-utils.js';
3
+ import { semanticEditIdentityFields } from './semanticEditIdentityRecords.js';
3
4
 
4
5
  export function projectSemanticEditScriptToSource(input = {}) {
5
6
  const script = input.script;
@@ -91,9 +92,7 @@ function sourceEditForOperation(operation, workerSourceText, headSourceText) {
91
92
  function projectionEditRecord(edit) {
92
93
  const deletedTextHash = hashSemanticValue(edit.current);
93
94
  const replacementTextHash = hashSemanticValue(edit.replacement);
94
- const semanticKey = semanticEditKey(edit);
95
- const semanticIdentityHash = hashSemanticValue(semanticIdentityRecord(edit, semanticKey));
96
- const sourceIdentityHash = hashSemanticValue(sourceIdentityRecord(edit));
95
+ const identity = semanticEditIdentityFields(edit);
97
96
  return compactRecord({
98
97
  operationId: edit.operationId,
99
98
  status: edit.alreadyApplied ? 'already-applied' : 'applied',
@@ -107,11 +106,10 @@ function projectionEditRecord(edit) {
107
106
  symbolId: edit.symbolId,
108
107
  symbolName: edit.symbolName,
109
108
  symbolKind: edit.symbolKind,
110
- semanticKey,
111
- semanticIdentityHash,
112
- sourceIdentityHash,
109
+ ...identity,
110
+ operationContentHash: edit.operationContentHash,
113
111
  editContentHash: hashSemanticValue(compactRecord({
114
- semanticIdentityHash,
112
+ semanticIdentityHash: identity.semanticIdentityHash,
115
113
  deletedTextHash,
116
114
  replacementTextHash,
117
115
  status: edit.alreadyApplied ? 'already-applied' : 'applied'
@@ -128,35 +126,6 @@ function projectionEditRecord(edit) {
128
126
  });
129
127
  }
130
128
 
131
- function semanticEditKey(edit) {
132
- const scope = edit.symbolName
133
- ? `${edit.symbolKind ?? 'symbol'}:${edit.symbolName}`
134
- : edit.anchorKey ?? edit.regionId ?? edit.operationId;
135
- return ['semantic-edit', edit.kind ?? 'region', edit.changeKind ?? 'change', scope].filter(Boolean).join(':');
136
- }
137
-
138
- function semanticIdentityRecord(edit, semanticKey) {
139
- return compactRecord({
140
- semanticKey,
141
- kind: edit.kind,
142
- changeKind: edit.changeKind,
143
- regionKind: edit.regionKind,
144
- symbolName: edit.symbolName,
145
- symbolKind: edit.symbolKind
146
- });
147
- }
148
-
149
- function sourceIdentityRecord(edit) {
150
- return compactRecord({
151
- anchorKey: edit.anchorKey,
152
- conflictKey: edit.conflictKey,
153
- regionId: edit.regionId,
154
- sourcePath: edit.sourcePath,
155
- symbolId: edit.symbolId,
156
- semanticKey: semanticEditKey(edit)
157
- });
158
- }
159
-
160
129
  function semanticEditIdentity(operation) {
161
130
  const anchor = operation.anchor ?? {};
162
131
  return compactRecord({
@@ -169,7 +138,11 @@ function semanticEditIdentity(operation) {
169
138
  sourcePath: anchor.sourcePath,
170
139
  symbolId: anchor.symbolId,
171
140
  symbolName: anchor.symbolName,
172
- symbolKind: anchor.symbolKind
141
+ symbolKind: anchor.symbolKind,
142
+ semanticKey: operation.semanticKey,
143
+ semanticIdentityHash: operation.semanticIdentityHash,
144
+ sourceIdentityHash: operation.sourceIdentityHash,
145
+ operationContentHash: operation.operationContentHash
173
146
  });
174
147
  }
175
148
 
@@ -0,0 +1,54 @@
1
+ import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ export function semanticEditIdentityFields(record) {
4
+ const semanticKey = record.semanticKey ?? semanticEditKey(record);
5
+ return compactRecord({
6
+ semanticKey,
7
+ semanticIdentityHash: record.semanticIdentityHash ?? hashSemanticValue(semanticIdentityRecord(record, semanticKey)),
8
+ sourceIdentityHash: record.sourceIdentityHash ?? hashSemanticValue(sourceIdentityRecord(record, semanticKey))
9
+ });
10
+ }
11
+
12
+ export function semanticEditOperationContentHash(record) {
13
+ const semanticIdentityHash = record.semanticIdentityHash ?? semanticEditIdentityFields(record).semanticIdentityHash;
14
+ return hashSemanticValue(compactRecord({
15
+ semanticIdentityHash,
16
+ baseTextHash: record.baseTextHash,
17
+ workerTextHash: record.workerTextHash,
18
+ headTextHash: record.headTextHash,
19
+ status: record.status
20
+ }));
21
+ }
22
+
23
+ export function semanticEditKey(record) {
24
+ const scope = record.symbolName
25
+ ? `${record.symbolKind ?? 'symbol'}:${record.symbolName}`
26
+ : record.anchorKey ?? record.regionId ?? record.operationId ?? record.id;
27
+ return ['semantic-edit', record.kind ?? 'region', record.changeKind ?? 'change', scope].filter(Boolean).join(':');
28
+ }
29
+
30
+ function semanticIdentityRecord(record, semanticKey) {
31
+ return compactRecord({
32
+ semanticKey,
33
+ kind: record.kind,
34
+ changeKind: record.changeKind,
35
+ regionKind: record.regionKind,
36
+ symbolName: record.symbolName,
37
+ symbolKind: record.symbolKind
38
+ });
39
+ }
40
+
41
+ function sourceIdentityRecord(record, semanticKey) {
42
+ return compactRecord({
43
+ anchorKey: record.anchorKey,
44
+ conflictKey: record.conflictKey,
45
+ regionId: record.regionId,
46
+ sourcePath: record.sourcePath,
47
+ symbolId: record.symbolId,
48
+ semanticKey
49
+ });
50
+ }
51
+
52
+ function compactRecord(value) {
53
+ return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0)));
54
+ }
@@ -44,7 +44,11 @@ export function summarizeSemanticEditOperations(operations) {
44
44
  stale: byStatus.stale ?? 0,
45
45
  blocked: byStatus.blocked ?? 0,
46
46
  candidates: byStatus.candidate ?? 0,
47
- autoMergeCandidates: (byStatus.portable ?? 0) + (byStatus['already-applied'] ?? 0)
47
+ autoMergeCandidates: (byStatus.portable ?? 0) + (byStatus['already-applied'] ?? 0),
48
+ semanticKeys: uniqueStrings(operations.map((operation) => operation.semanticKey).filter(Boolean)),
49
+ semanticIdentityHashes: uniqueStrings(operations.map((operation) => operation.semanticIdentityHash).filter(Boolean)),
50
+ sourceIdentityHashes: uniqueStrings(operations.map((operation) => operation.sourceIdentityHash).filter(Boolean)),
51
+ operationContentHashes: uniqueStrings(operations.map((operation) => operation.operationContentHash).filter(Boolean))
48
52
  };
49
53
  }
50
54
 
@@ -13,6 +13,7 @@ import {
13
13
  summarizeSemanticEditOperations
14
14
  } from './semanticEditScriptClassification.js';
15
15
  import { sourceTextForSpan } from './sourceTextForSpan.js';
16
+ import { semanticEditIdentityFields, semanticEditOperationContentHash } from './semanticEditIdentityRecords.js';
16
17
 
17
18
  export { SemanticEditScriptAdmissionStatuses };
18
19
 
@@ -137,42 +138,48 @@ function semanticEditOperation(region, index, context, input) {
137
138
  const baseText = spanText(context.base, baseSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.before?.sourceSpan ?? region.sourceSpan);
138
139
  const workerText = spanText(context.worker, workerSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.after?.sourceSpan ?? region.sourceSpan);
139
140
  const headText = spanText(context.head, headSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.head?.sourceSpan ?? baseSymbol?.sourceSpan);
141
+ const anchor = compactRecord({
142
+ key: anchorKey,
143
+ conflictKey: region.conflictKey ?? `region:${anchorKey}`,
144
+ regionId: region.id,
145
+ regionKind: region.regionKind,
146
+ granularity: region.granularity,
147
+ language: region.language ?? context.workerChangeSet.language,
148
+ sourcePath: region.sourcePath ?? context.workerChangeSet.sourcePath,
149
+ symbolId: region.symbolId ?? workerSymbol?.id ?? baseSymbol?.id,
150
+ symbolName: region.symbolName ?? workerSymbol?.name ?? baseSymbol?.name,
151
+ symbolKind: region.symbolKind ?? workerSymbol?.kind ?? baseSymbol?.kind,
152
+ sourceSpan: workerSymbol?.sourceSpan ?? region.sourceSpan
153
+ });
154
+ const hashes = compactRecord({
155
+ baseSourceHash: context.workerChangeSet.beforeHash,
156
+ workerSourceHash: context.workerChangeSet.afterHash,
157
+ headSourceHash: context.headChangeSet?.afterHash,
158
+ baseSpanHash: baseSymbol?.spanHash,
159
+ workerSpanHash: workerSymbol?.spanHash,
160
+ headSpanHash: headSymbol?.spanHash,
161
+ baseTextHash: baseText === undefined ? undefined : hashSemanticValue(baseText),
162
+ workerTextHash: workerText === undefined ? undefined : hashSemanticValue(workerText),
163
+ headTextHash: headText === undefined ? undefined : hashSemanticValue(headText),
164
+ beforeSignatureHash: workerSymbol?.beforeSignatureHash ?? baseSymbol?.signatureHash,
165
+ afterSignatureHash: workerSymbol?.afterSignatureHash ?? workerSymbol?.signatureHash
166
+ });
167
+ const identityRecord = semanticEditIdentityRecord({ kind, region, anchor });
168
+ const identity = semanticEditIdentityFields(identityRecord);
140
169
  return compactRecord({
141
170
  id: `semantic_edit_op_${idFragment(firstString(input.id, anchorKey, index))}`,
142
171
  kind,
143
172
  changeKind: region.changeKind,
144
- anchor: compactRecord({
145
- key: anchorKey,
146
- conflictKey: region.conflictKey ?? `region:${anchorKey}`,
147
- regionId: region.id,
148
- regionKind: region.regionKind,
149
- granularity: region.granularity,
150
- language: region.language ?? context.workerChangeSet.language,
151
- sourcePath: region.sourcePath ?? context.workerChangeSet.sourcePath,
152
- symbolId: region.symbolId ?? workerSymbol?.id ?? baseSymbol?.id,
153
- symbolName: region.symbolName ?? workerSymbol?.name ?? baseSymbol?.name,
154
- symbolKind: region.symbolKind ?? workerSymbol?.kind ?? baseSymbol?.kind,
155
- sourceSpan: workerSymbol?.sourceSpan ?? region.sourceSpan
156
- }),
173
+ anchor,
174
+ ...identity,
157
175
  spans: compactRecord({
158
176
  base: baseSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.before?.sourceSpan,
159
177
  worker: workerSymbol?.sourceSpan ?? region.metadata?.changedRegionProjection?.after?.sourceSpan ?? region.sourceSpan,
160
178
  head: headSymbol?.sourceSpan
161
179
  }),
162
- hashes: compactRecord({
163
- baseSourceHash: context.workerChangeSet.beforeHash,
164
- workerSourceHash: context.workerChangeSet.afterHash,
165
- headSourceHash: context.headChangeSet?.afterHash,
166
- baseSpanHash: baseSymbol?.spanHash,
167
- workerSpanHash: workerSymbol?.spanHash,
168
- headSpanHash: headSymbol?.spanHash,
169
- baseTextHash: baseText === undefined ? undefined : hashSemanticValue(baseText),
170
- workerTextHash: workerText === undefined ? undefined : hashSemanticValue(workerText),
171
- headTextHash: headText === undefined ? undefined : hashSemanticValue(headText),
172
- beforeSignatureHash: workerSymbol?.beforeSignatureHash ?? baseSymbol?.signatureHash,
173
- afterSignatureHash: workerSymbol?.afterSignatureHash ?? workerSymbol?.signatureHash
174
- }),
180
+ hashes,
175
181
  status: classification.status,
182
+ operationContentHash: semanticEditOperationContentHash({ ...identityRecord, ...identity, ...hashes, status: classification.status }),
176
183
  reanchor: classification.reanchor,
177
184
  readiness: classification.readiness,
178
185
  confidence: classification.confidence,
@@ -185,6 +192,21 @@ function semanticEditOperation(region, index, context, input) {
185
192
  });
186
193
  }
187
194
 
195
+ function semanticEditIdentityRecord(input) {
196
+ return {
197
+ kind: input.kind,
198
+ changeKind: input.region.changeKind,
199
+ anchorKey: input.anchor.key,
200
+ conflictKey: input.anchor.conflictKey,
201
+ regionId: input.anchor.regionId,
202
+ regionKind: input.anchor.regionKind,
203
+ sourcePath: input.anchor.sourcePath,
204
+ symbolId: input.anchor.symbolId,
205
+ symbolName: input.anchor.symbolName,
206
+ symbolKind: input.anchor.symbolKind
207
+ };
208
+ }
209
+
188
210
  function semanticEditOperationKind(region) {
189
211
  const prefix = region.changeKind === 'added' ? 'add' : region.changeKind === 'removed' ? 'remove' : 'replace';
190
212
  const kind = String(region.regionKind ?? region.granularity ?? 'region');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.84",
3
+ "version": "0.2.85",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",