@ahtmljs/schema 0.1.0
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/dist/diff.d.ts +16 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +90 -0
- package/dist/diff.js.map +1 -0
- package/dist/format-compact.d.ts +29 -0
- package/dist/format-compact.d.ts.map +1 -0
- package/dist/format-compact.js +567 -0
- package/dist/format-compact.js.map +1 -0
- package/dist/format-json.d.ts +17 -0
- package/dist/format-json.d.ts.map +1 -0
- package/dist/format-json.js +39 -0
- package/dist/format-json.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/snapshot.d.ts +49 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +109 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/types.d.ts +256 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +17 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +179 -0
- package/dist/validate.js.map +1 -0
- package/package.json +23 -0
- package/src/schema.json +222 -0
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot diffing.
|
|
3
|
+
*
|
|
4
|
+
* Given two snapshots (old, new), produce a minimal DiffChange list so
|
|
5
|
+
* agents can incrementally update their world model without re-fetching
|
|
6
|
+
* the whole page.
|
|
7
|
+
*
|
|
8
|
+
* Diff strategy: structural, by entity/action id. We do NOT attempt deep
|
|
9
|
+
* field-level patches inside an entity — we replace the whole entity if
|
|
10
|
+
* any field changed. This trades patch size for diff cost, and the size
|
|
11
|
+
* trade-off is fine because individual entities are already tiny.
|
|
12
|
+
*/
|
|
13
|
+
import type { Snapshot, SnapshotDiff } from './types.js';
|
|
14
|
+
export declare function diff(prev: Snapshot, next: Snapshot): SnapshotDiff;
|
|
15
|
+
export declare function applyDiff(prev: Snapshot, d: SnapshotDiff): Snapshot;
|
|
16
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAA8B,MAAM,YAAY,CAAC;AAGrF,wBAAgB,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG,YAAY,CA6CjE;AAMD,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,GAAG,QAAQ,CAmBnE"}
|
package/dist/diff.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot diffing.
|
|
3
|
+
*
|
|
4
|
+
* Given two snapshots (old, new), produce a minimal DiffChange list so
|
|
5
|
+
* agents can incrementally update their world model without re-fetching
|
|
6
|
+
* the whole page.
|
|
7
|
+
*
|
|
8
|
+
* Diff strategy: structural, by entity/action id. We do NOT attempt deep
|
|
9
|
+
* field-level patches inside an entity — we replace the whole entity if
|
|
10
|
+
* any field changed. This trades patch size for diff cost, and the size
|
|
11
|
+
* trade-off is fine because individual entities are already tiny.
|
|
12
|
+
*/
|
|
13
|
+
import { computeEtag } from './snapshot.js';
|
|
14
|
+
export function diff(prev, next) {
|
|
15
|
+
const changes = [];
|
|
16
|
+
const prevEntities = new Map(prev.entities.map((e) => [e.id, e]));
|
|
17
|
+
const nextEntities = new Map(next.entities.map((e) => [e.id, e]));
|
|
18
|
+
for (const [id, e] of nextEntities) {
|
|
19
|
+
const old = prevEntities.get(id);
|
|
20
|
+
if (!old) {
|
|
21
|
+
changes.push({ op: 'add', entity: e });
|
|
22
|
+
}
|
|
23
|
+
else if (!sameJson(old, e)) {
|
|
24
|
+
changes.push({ op: 'update', id, patch: e });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
for (const id of prevEntities.keys()) {
|
|
28
|
+
if (!nextEntities.has(id)) {
|
|
29
|
+
changes.push({ op: 'remove', id });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const prevActions = new Map(prev.actions.map((a) => [a.id, a]));
|
|
33
|
+
const nextActions = new Map(next.actions.map((a) => [a.id, a]));
|
|
34
|
+
for (const [id, a] of nextActions) {
|
|
35
|
+
const old = prevActions.get(id);
|
|
36
|
+
if (!old) {
|
|
37
|
+
changes.push({ op: 'add_action', action: a });
|
|
38
|
+
}
|
|
39
|
+
else if (!sameJson(old, a)) {
|
|
40
|
+
changes.push({ op: 'remove_action', id });
|
|
41
|
+
changes.push({ op: 'add_action', action: a });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const id of prevActions.keys()) {
|
|
45
|
+
if (!nextActions.has(id)) {
|
|
46
|
+
changes.push({ op: 'remove_action', id });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
ahtml: '0.1',
|
|
51
|
+
url: next.url,
|
|
52
|
+
from_etag: prev.etag ?? computeEtag(prev),
|
|
53
|
+
to_etag: next.etag ?? computeEtag(next),
|
|
54
|
+
changes,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function sameJson(a, b) {
|
|
58
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
59
|
+
}
|
|
60
|
+
export function applyDiff(prev, d) {
|
|
61
|
+
const entities = new Map(prev.entities.map((e) => [e.id, e]));
|
|
62
|
+
const actions = new Map(prev.actions.map((a) => [a.id, a]));
|
|
63
|
+
for (const c of d.changes) {
|
|
64
|
+
switch (c.op) {
|
|
65
|
+
case 'add':
|
|
66
|
+
entities.set(c.entity.id, c.entity);
|
|
67
|
+
break;
|
|
68
|
+
case 'remove':
|
|
69
|
+
entities.delete(c.id);
|
|
70
|
+
break;
|
|
71
|
+
case 'update':
|
|
72
|
+
entities.set(c.id, c.patch);
|
|
73
|
+
break;
|
|
74
|
+
case 'add_action':
|
|
75
|
+
actions.set(c.action.id, c.action);
|
|
76
|
+
break;
|
|
77
|
+
case 'remove_action':
|
|
78
|
+
actions.delete(c.id);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
...prev,
|
|
84
|
+
fetched_at: new Date().toISOString(),
|
|
85
|
+
etag: d.to_etag,
|
|
86
|
+
entities: [...entities.values()],
|
|
87
|
+
actions: [...actions.values()],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=diff.js.map
|
package/dist/diff.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact text serializer — the token-optimal wire format.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists: LLMs tokenize key-value lines and short identifiers much
|
|
5
|
+
* more efficiently than JSON. By stripping JSON's structural overhead
|
|
6
|
+
* (quotes, braces, colons, commas, escapes, repeated property names) and
|
|
7
|
+
* collapsing common shapes (Money → "1999 USD", Stock → "in_stock (42)"),
|
|
8
|
+
* the same snapshot uses 3–5× fewer tokens.
|
|
9
|
+
*
|
|
10
|
+
* Combined with the snapshot itself replacing the underlying HTML, the
|
|
11
|
+
* end-to-end agent-token reduction is typically 80–200×.
|
|
12
|
+
*
|
|
13
|
+
* The format is human-readable, line-oriented, and round-trippable
|
|
14
|
+
* (see fromCompact). Lossless against canonical JSON.
|
|
15
|
+
*
|
|
16
|
+
* Grammar (informal):
|
|
17
|
+
*
|
|
18
|
+
* snapshot = envelope NL block*
|
|
19
|
+
* envelope = ("@" key value NL)+
|
|
20
|
+
* block = (entity | action | named) NL body
|
|
21
|
+
* entity = "[" type ":" id "]"
|
|
22
|
+
* action = "(action) " id
|
|
23
|
+
* named = "@" name # policy, provenance, meta, links, schemas
|
|
24
|
+
* body = (" " key ": " value NL)*
|
|
25
|
+
*/
|
|
26
|
+
import type { Snapshot } from './types.js';
|
|
27
|
+
export declare function toCompact(s: Snapshot): string;
|
|
28
|
+
export declare function fromCompact(text: string): Snapshot;
|
|
29
|
+
//# sourceMappingURL=format-compact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-compact.d.ts","sourceRoot":"","sources":["../src/format-compact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EACV,QAAQ,EAeT,MAAM,YAAY,CAAC;AAEpB,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAsD7C;AAgPD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CA0ElD"}
|