capdag 0.166.402 → 0.168.411
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/build-browser.js +24 -6
- package/capdag.js +7 -3
- package/capdag.test.js +24 -14
- package/package.json +1 -1
package/build-browser.js
CHANGED
|
@@ -31,13 +31,14 @@ const outDir = process.argv[2]
|
|
|
31
31
|
fs.mkdirSync(outDir, { recursive: true });
|
|
32
32
|
|
|
33
33
|
function stripCJS(src) {
|
|
34
|
-
// Strip
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
34
|
+
// Strip every top-level `require('tagged-urn')` (regardless of the
|
|
35
|
+
// destructure shape — the source also pulls `valuesMatch` and
|
|
36
|
+
// `scoreTagValue` out of the same package), the leading "Import
|
|
37
|
+
// TaggedUrn" comment, and the trailing `module.exports` block.
|
|
38
|
+
// The IIFE shim further down rebinds the names from `window.*`.
|
|
38
39
|
return src
|
|
39
40
|
.replace(/^\/\/.*Import TaggedUrn.*\n/m, '')
|
|
40
|
-
.replace(/^const\s*\{
|
|
41
|
+
.replace(/^const\s*\{[^}]*\}\s*=\s*require\s*\(\s*['"]tagged-urn['"]\s*\)\s*;?\s*$/gm, '')
|
|
41
42
|
.replace(/^module\.exports\s*=\s*\{[\s\S]*?\};?\s*$/m, '');
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -60,6 +61,11 @@ window.TaggedUrnBuilder = TaggedUrnBuilder;
|
|
|
60
61
|
window.UrnMatcher = UrnMatcher;
|
|
61
62
|
window.TaggedUrnError = TaggedUrnError;
|
|
62
63
|
window.TaggedUrnErrorCodes = ErrorCodes;
|
|
64
|
+
// scoreTagValue / valuesMatch are exported by the npm package and
|
|
65
|
+
// consumed by capdag.js. The browser shim depends on them being on
|
|
66
|
+
// window so the rebinder at the top of capdag.js can find them.
|
|
67
|
+
window.taggedUrnScoreTagValue = scoreTagValue;
|
|
68
|
+
window.taggedUrnValuesMatch = valuesMatch;
|
|
63
69
|
|
|
64
70
|
})();
|
|
65
71
|
`;
|
|
@@ -102,10 +108,22 @@ ${parserSrc}
|
|
|
102
108
|
(function() {
|
|
103
109
|
'use strict';
|
|
104
110
|
|
|
105
|
-
const { TaggedUrn } = window;
|
|
111
|
+
const { TaggedUrn, taggedUrnScoreTagValue, taggedUrnValuesMatch } = window;
|
|
106
112
|
if (!TaggedUrn) {
|
|
107
113
|
throw new Error('TaggedUrn global is not defined. Load tagged-urn.js before capdag.js.');
|
|
108
114
|
}
|
|
115
|
+
if (typeof taggedUrnScoreTagValue !== 'function' || typeof taggedUrnValuesMatch !== 'function') {
|
|
116
|
+
throw new Error('tagged-urn.js browser bundle is out of date — missing taggedUrnScoreTagValue / taggedUrnValuesMatch.');
|
|
117
|
+
}
|
|
118
|
+
// The capdag.js source destructures these out of `require('tagged-urn')`
|
|
119
|
+
// as `{ valuesMatch: taggedUrnValuesMatch }` and `{ scoreTagValue }`.
|
|
120
|
+
// stripCJS removed the require lines; rebind the same names so the
|
|
121
|
+
// downstream code (e.g. `taggedUrnValuesMatch(inst, patt)` at the
|
|
122
|
+
// six-form matcher, `scoreTagValue(value)` in y-axis specificity)
|
|
123
|
+
// resolves cleanly.
|
|
124
|
+
// taggedUrnValuesMatch is already bound by the destructure above; alias
|
|
125
|
+
// scoreTagValue under its unprefixed name.
|
|
126
|
+
const scoreTagValue = taggedUrnScoreTagValue;
|
|
109
127
|
|
|
110
128
|
${inlinedParser}
|
|
111
129
|
|
package/capdag.js
CHANGED
|
@@ -5381,13 +5381,17 @@ class Machine {
|
|
|
5381
5381
|
// uses `edge_<idx>` unconditionally — there is no privileged tag (such
|
|
5382
5382
|
// as the legacy `op=…` tag) we can derive a friendlier name from, so
|
|
5383
5383
|
// we mirror the same pure-index scheme here.
|
|
5384
|
+
// Number aliases by position in the canonical (sorted) edge order so
|
|
5385
|
+
// that two graphs with the same edges in different insertion orders
|
|
5386
|
+
// produce identical notation. Without this the alias number tracks
|
|
5387
|
+
// insertion order and serialization is non-canonical.
|
|
5384
5388
|
const aliases = new Map();
|
|
5385
|
-
|
|
5389
|
+
edgeOrder.forEach((idx, position) => {
|
|
5386
5390
|
const edge = this._edges[idx];
|
|
5387
|
-
const alias = `edge_${
|
|
5391
|
+
const alias = `edge_${position}`;
|
|
5388
5392
|
const capStr = edge.capUrn.toString();
|
|
5389
5393
|
aliases.set(alias, { edgeIdx: idx, capStr });
|
|
5390
|
-
}
|
|
5394
|
+
});
|
|
5391
5395
|
|
|
5392
5396
|
// Step 3: Generate node names
|
|
5393
5397
|
// Collect all unique media URNs, assign names in order of first appearance
|
package/capdag.test.js
CHANGED
|
@@ -164,13 +164,14 @@ function test003_directionMatching() {
|
|
|
164
164
|
assert(wildcardCap.accepts(request), 'Wildcard direction should match any');
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
// TEST004: Test that unquoted keys and values are normalized to lowercase
|
|
167
|
+
// TEST004: Test that unquoted keys and values are normalized to lowercase.
|
|
168
|
+
// Key lookup is case-insensitive: uppercase variants of `ext` resolve
|
|
169
|
+
// to the same keyed tag.
|
|
168
170
|
function test004_unquotedValuesLowercased() {
|
|
169
171
|
const cap = CapUrn.fromString('cap:ext=pdf;generate;in=media:void;out="media:record;textable"');
|
|
170
172
|
assert(cap.hasMarkerTag('generate'), 'Unquoted value should be lowercased');
|
|
171
173
|
assertEqual(cap.getTag('ext'), 'pdf', 'Unquoted value should be lowercased');
|
|
172
|
-
|
|
173
|
-
assertEqual(cap.getTag('OP'), 'generate', 'Key lookup should be case-insensitive');
|
|
174
|
+
assertEqual(cap.getTag('EXT'), 'pdf', 'Key lookup should be case-insensitive');
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
// TEST005: Test that quoted values preserve case while unquoted are lowercased
|
|
@@ -363,15 +364,16 @@ function test020_specificity() {
|
|
|
363
364
|
'out=record=2, in=*->0, y=test marker=2 -> 20002');
|
|
364
365
|
}
|
|
365
366
|
|
|
366
|
-
// TEST021: Test builder creates cap URN with
|
|
367
|
+
// TEST021: Test builder creates cap URN with marker + keyed tags and direction specs.
|
|
368
|
+
// `op` is no longer a special key — operation names are markers (value-less tags).
|
|
367
369
|
function test021_builder() {
|
|
368
370
|
const cap = new CapUrnBuilder()
|
|
369
371
|
.inSpec('media:void')
|
|
370
372
|
.outSpec('media:object')
|
|
371
|
-
.
|
|
373
|
+
.marker('generate')
|
|
372
374
|
.tag('ext', 'pdf')
|
|
373
375
|
.build();
|
|
374
|
-
assert(cap.hasMarkerTag('generate'), 'Builder should set
|
|
376
|
+
assert(cap.hasMarkerTag('generate'), 'Builder should set the generate marker');
|
|
375
377
|
assertEqual(cap.getTag('ext'), 'pdf', 'Builder should set ext');
|
|
376
378
|
assertEqual(cap.getInSpec(), 'media:void', 'Builder should set inSpec');
|
|
377
379
|
assertEqual(cap.getOutSpec(), 'media:object', 'Builder should set outSpec');
|
|
@@ -2906,8 +2908,9 @@ function testMachine_lineBasedFormatSerialization() {
|
|
|
2906
2908
|
const lineBased = g.toMachineNotationFormatted('line-based');
|
|
2907
2909
|
assert(!lineBased.includes('['), 'Line-based format must not contain brackets');
|
|
2908
2910
|
assert(!lineBased.includes(']'), 'Line-based format must not contain brackets');
|
|
2909
|
-
|
|
2910
|
-
assert(lineBased.includes('
|
|
2911
|
+
// Aliases are pure-index `edge_<N>` (no privileged tag to derive a friendlier name).
|
|
2912
|
+
assert(lineBased.includes('edge_0 cap:'), 'Should contain header');
|
|
2913
|
+
assert(lineBased.includes('-> edge_0 ->'), 'Should contain wiring');
|
|
2911
2914
|
|
|
2912
2915
|
// Round-trip
|
|
2913
2916
|
const reparsed = Machine.fromString(lineBased);
|
|
@@ -3177,8 +3180,9 @@ function testMachine_serializeSingleEdge() {
|
|
|
3177
3180
|
false
|
|
3178
3181
|
)]);
|
|
3179
3182
|
const notation = g.toMachineNotation();
|
|
3180
|
-
|
|
3181
|
-
assert(notation.includes('
|
|
3183
|
+
// Aliases are pure-index `edge_<N>` (no privileged tag to derive a friendlier name).
|
|
3184
|
+
assert(notation.includes('[edge_0 '), 'Should use edge_0 alias: ' + notation);
|
|
3185
|
+
assert(notation.includes('-> edge_0 ->'), 'Should have edge_0 in wiring: ' + notation);
|
|
3182
3186
|
assert(notation.includes('[n0 ->'), 'Should use n0 for source: ' + notation);
|
|
3183
3187
|
assert(notation.includes('-> n1]'), 'Should use n1 for target: ' + notation);
|
|
3184
3188
|
}
|
|
@@ -3298,6 +3302,8 @@ function testMachine_multilineSerializeFormat() {
|
|
|
3298
3302
|
assert(g.isEquivalent(reparsed), 'Multi-line round-trip failed');
|
|
3299
3303
|
}
|
|
3300
3304
|
|
|
3305
|
+
// Aliases are pure-index `edge_<N>` regardless of the cap's tags; there is
|
|
3306
|
+
// no privileged `op` tag to derive a friendlier name from.
|
|
3301
3307
|
function testMachine_aliasFromOpTag() {
|
|
3302
3308
|
const g = new Machine([new MachineEdge(
|
|
3303
3309
|
[MediaUrn.fromString('media:pdf')],
|
|
@@ -3306,7 +3312,7 @@ function testMachine_aliasFromOpTag() {
|
|
|
3306
3312
|
false
|
|
3307
3313
|
)]);
|
|
3308
3314
|
const notation = g.toMachineNotation();
|
|
3309
|
-
assert(notation.includes('[
|
|
3315
|
+
assert(notation.includes('[edge_0 '), 'Expected edge_0 alias, got: ' + notation);
|
|
3310
3316
|
}
|
|
3311
3317
|
|
|
3312
3318
|
function testMachine_aliasFallbackWithoutOpTag() {
|
|
@@ -3320,6 +3326,7 @@ function testMachine_aliasFallbackWithoutOpTag() {
|
|
|
3320
3326
|
assert(notation.includes('edge_'), 'Expected fallback alias, got: ' + notation);
|
|
3321
3327
|
}
|
|
3322
3328
|
|
|
3329
|
+
// Pure-index aliases inherently disambiguate edges that share a marker tag.
|
|
3323
3330
|
function testMachine_duplicateOpTagsDisambiguated() {
|
|
3324
3331
|
const g = new Machine([
|
|
3325
3332
|
new MachineEdge(
|
|
@@ -3336,8 +3343,8 @@ function testMachine_duplicateOpTagsDisambiguated() {
|
|
|
3336
3343
|
),
|
|
3337
3344
|
]);
|
|
3338
3345
|
const notation = g.toMachineNotation();
|
|
3339
|
-
assert(notation.includes('
|
|
3340
|
-
'
|
|
3346
|
+
assert(notation.includes('edge_0') && notation.includes('edge_1'),
|
|
3347
|
+
'Two edges must serialize with two distinct aliases: ' + notation);
|
|
3341
3348
|
}
|
|
3342
3349
|
|
|
3343
3350
|
// --- Machine builder tests ---
|
|
@@ -3575,7 +3582,10 @@ function testMachine_toMermaid_linearChain() {
|
|
|
3575
3582
|
);
|
|
3576
3583
|
const mermaid = machine.toMermaid();
|
|
3577
3584
|
assert(mermaid.startsWith('flowchart LR'), 'Should start with flowchart LR');
|
|
3578
|
-
|
|
3585
|
+
// Edge labels are pure-index `edge_<N>` aliases from the canonical
|
|
3586
|
+
// serializer (the input alias name is not preserved in the rendered
|
|
3587
|
+
// diagram — it's a serialization artefact, not part of the machine).
|
|
3588
|
+
assert(mermaid.includes('edge_0'), 'Should include edge_0 label');
|
|
3579
3589
|
assert(mermaid.includes('media:pdf'), 'Should include media:pdf node');
|
|
3580
3590
|
assert(mermaid.includes('media:textable;txt'), 'Should include media:textable;txt node');
|
|
3581
3591
|
assert(mermaid.includes('-->'), 'Should include arrow');
|
package/package.json
CHANGED