@bablr/agast-helpers 0.10.10 → 0.11.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/README.md +1 -1
- package/lib/b-list-keyed.js +1 -0
- package/lib/b-list.js +1 -0
- package/lib/b-map.js +1 -0
- package/lib/b-set.js +1 -0
- package/lib/builders.js +917 -115
- package/lib/debug.js +39 -0
- package/lib/debug.register.js +5 -0
- package/lib/iterable.js +170 -0
- package/lib/object.js +52 -3
- package/lib/parse.js +30 -0
- package/lib/path.js +580 -634
- package/lib/print.js +45 -22
- package/lib/shorthand.js +4 -30
- package/lib/spans.js +0 -163
- package/lib/stream.js +345 -196
- package/lib/symbols.js +1 -0
- package/lib/tags.js +256 -77
- package/lib/template.js +19 -16
- package/lib/tree.js +49 -44
- package/package.json +14 -8
- package/lib/btree.js +0 -1
package/lib/print.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { freezeRecord } from '@bablr/record';
|
|
1
2
|
import {
|
|
2
3
|
DoctypeTag,
|
|
3
4
|
OpenNodeTag,
|
|
@@ -9,8 +10,9 @@ import {
|
|
|
9
10
|
LiteralTag,
|
|
10
11
|
AttributeDefinition,
|
|
11
12
|
BindingTag,
|
|
13
|
+
StreamTag,
|
|
12
14
|
} from './symbols.js';
|
|
13
|
-
import {
|
|
15
|
+
import { parseObject } from './builders.js';
|
|
14
16
|
|
|
15
17
|
let { isInteger, isFinite } = Number;
|
|
16
18
|
let { isArray } = Array;
|
|
@@ -46,19 +48,22 @@ export const printExpression = (expr) => {
|
|
|
46
48
|
}
|
|
47
49
|
} else if (isArray(expr)) {
|
|
48
50
|
return printArray(expr);
|
|
51
|
+
} else if (isObject(expr)) {
|
|
52
|
+
return printObject(expr);
|
|
49
53
|
} else {
|
|
50
54
|
throw new Error();
|
|
51
55
|
}
|
|
52
56
|
};
|
|
53
57
|
|
|
54
58
|
export const printAttributes = (attributes) => {
|
|
55
|
-
const printed =
|
|
59
|
+
const printed =
|
|
60
|
+
attributes && printObject(isString(attributes) ? parseObject(attributes) : attributes);
|
|
56
61
|
return !printed || printed === '{}' ? '' : printed;
|
|
57
62
|
};
|
|
58
63
|
|
|
59
64
|
export const printIdentifierPath = (path) => {
|
|
60
|
-
return
|
|
61
|
-
.
|
|
65
|
+
return Array.prototype.map
|
|
66
|
+
.call(path, (segment) => {
|
|
62
67
|
let { name, type } = segment;
|
|
63
68
|
if (name) {
|
|
64
69
|
return printIdentifier(name);
|
|
@@ -131,19 +136,12 @@ export const printReference = (ref) => {
|
|
|
131
136
|
};
|
|
132
137
|
|
|
133
138
|
export const printBinding = (binding) => {
|
|
134
|
-
let {
|
|
135
|
-
return `:${
|
|
136
|
-
segments.length ? segments.map((segment) => printBindingSegment(segment)).join('/') : ''
|
|
137
|
-
}:`;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
export const printBindingSegment = (segment) => {
|
|
141
|
-
let { type, name } = segment;
|
|
139
|
+
let { type, name } = binding;
|
|
142
140
|
if (type) {
|
|
143
141
|
if (type !== '..') throw new Error();
|
|
144
|
-
return type
|
|
142
|
+
return `:${type}:`;
|
|
145
143
|
} else if (name) {
|
|
146
|
-
return printIdentifier(name)
|
|
144
|
+
return `:${printIdentifier(name.description)}:`;
|
|
147
145
|
} else {
|
|
148
146
|
throw new Error();
|
|
149
147
|
}
|
|
@@ -158,9 +156,7 @@ export const printBindingTag = (tag) => {
|
|
|
158
156
|
};
|
|
159
157
|
|
|
160
158
|
export const printNullTag = (tag) => {
|
|
161
|
-
if (tag && tag.type !== NullTag)
|
|
162
|
-
throw new Error();
|
|
163
|
-
}
|
|
159
|
+
if (tag && tag.type !== NullTag && tag !== 'null') throw new Error();
|
|
164
160
|
|
|
165
161
|
return 'null';
|
|
166
162
|
};
|
|
@@ -174,7 +170,7 @@ export const printName = (type) => {
|
|
|
174
170
|
};
|
|
175
171
|
|
|
176
172
|
export const printType = (type) => {
|
|
177
|
-
return typeof type === 'symbol' ? type.description : String(type);
|
|
173
|
+
return type == null ? '' : typeof type === 'symbol' ? type.description : String(type);
|
|
178
174
|
};
|
|
179
175
|
|
|
180
176
|
export const printDoctypeTag = (tag) => {
|
|
@@ -194,7 +190,14 @@ export const printLiteralTag = (tag) => {
|
|
|
194
190
|
return printString(tag.value);
|
|
195
191
|
};
|
|
196
192
|
|
|
197
|
-
|
|
193
|
+
let defaultFlags = freezeRecord({
|
|
194
|
+
array: false,
|
|
195
|
+
expression: false,
|
|
196
|
+
intrinsic: false,
|
|
197
|
+
hasGap: false,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
export const printReferenceFlags = (flags = defaultFlags) => {
|
|
198
201
|
let array = flags.array ? `[]` : '';
|
|
199
202
|
let plus = flags.expression ? '+' : '';
|
|
200
203
|
let star = flags.intrinsic ? '*' : '';
|
|
@@ -249,6 +252,14 @@ export const printSelfClosingNodeTag = (tag, literalValue) => {
|
|
|
249
252
|
return `<${printNodeFlags(flags)}${typeFrag}${nameFrag}${literalFrag}${attributesFrag} />`;
|
|
250
253
|
};
|
|
251
254
|
|
|
255
|
+
export const printStreamTag = (tag) => {
|
|
256
|
+
if (tag?.type !== StreamTag) throw new Error();
|
|
257
|
+
|
|
258
|
+
let { processPath, stream } = tag.value;
|
|
259
|
+
|
|
260
|
+
return `<${Array.prototype.join.call(processPath, '.')}-${stream}>`;
|
|
261
|
+
};
|
|
262
|
+
|
|
252
263
|
export const printCloseNodeTag = (tag) => {
|
|
253
264
|
if (tag?.type !== CloseNodeTag) throw new Error();
|
|
254
265
|
|
|
@@ -261,7 +272,7 @@ export const printAttributeDefinition = (tag) => {
|
|
|
261
272
|
let { path, value } = tag.value;
|
|
262
273
|
|
|
263
274
|
return `{ ${printIdentifierPath(
|
|
264
|
-
|
|
275
|
+
Array.prototype.map.call(path, (name) => freeze({ type: null, name })),
|
|
265
276
|
)}: ${printExpression(value)} }`;
|
|
266
277
|
};
|
|
267
278
|
|
|
@@ -275,13 +286,25 @@ const printers = {
|
|
|
275
286
|
[ReferenceTag]: printReferenceTag,
|
|
276
287
|
[OpenNodeTag]: printOpenNodeTag,
|
|
277
288
|
[CloseNodeTag]: printCloseNodeTag,
|
|
289
|
+
[StreamTag]: printStreamTag,
|
|
278
290
|
[AttributeDefinition]: printAttributeDefinition,
|
|
279
291
|
};
|
|
280
292
|
|
|
281
293
|
export const printTag = (tag) => {
|
|
294
|
+
if (tag == null || isString(tag)) return tag;
|
|
282
295
|
if (!isObject(tag)) throw new Error();
|
|
283
296
|
|
|
284
|
-
let printer = printers[tag
|
|
297
|
+
let printer = printers[tag.type];
|
|
298
|
+
|
|
299
|
+
return printer ? printer(tag) : tag;
|
|
300
|
+
};
|
|
285
301
|
|
|
286
|
-
|
|
302
|
+
export const printIOTag = (tag) => {
|
|
303
|
+
if (tag == null || isString(tag)) return tag;
|
|
304
|
+
if (!isObject(tag)) throw new Error();
|
|
305
|
+
|
|
306
|
+
if (tag.type === StreamTag) {
|
|
307
|
+
return printStreamTag(tag);
|
|
308
|
+
}
|
|
309
|
+
return printTag(tag);
|
|
287
310
|
};
|
package/lib/shorthand.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
buildLiteralTag,
|
|
7
7
|
buildOpenFragmentTag,
|
|
8
8
|
buildOpenCoverTag,
|
|
9
|
+
parseReferenceTag,
|
|
9
10
|
} from './builders.js';
|
|
10
|
-
import {
|
|
11
|
-
import { buildReferenceTag, treeFromStreamSync } from './tree.js';
|
|
11
|
+
import { treeFromStream } from './tree.js';
|
|
12
12
|
|
|
13
13
|
export * from './builders.js';
|
|
14
14
|
|
|
@@ -25,34 +25,8 @@ const stripArray = (val) => {
|
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
export const parseReference = (str) => {
|
|
29
|
-
let {
|
|
30
|
-
1: type,
|
|
31
|
-
2: namedType,
|
|
32
|
-
3: name,
|
|
33
|
-
4: array,
|
|
34
|
-
5: expressionToken,
|
|
35
|
-
6: intrinsicToken,
|
|
36
|
-
7: hasGapToken,
|
|
37
|
-
} = /^\s*(?:([.#@_])|(#)?([a-zA-Z\u{80}-\u{10ffff}][a-zA-Z0-9_\u{80}-\u{10ffff}-]*))\s*(\[\])?\s*(\+)?(\*)?(\$)?\s*$/u.exec(
|
|
38
|
-
str,
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
let flags = freeze({
|
|
42
|
-
array: !!array,
|
|
43
|
-
expression: !!expressionToken,
|
|
44
|
-
intrinsic: !!intrinsicToken,
|
|
45
|
-
hasGap: !!hasGapToken,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
type = type || namedType || null;
|
|
49
|
-
name = name || null;
|
|
50
|
-
|
|
51
|
-
return buildReferenceTag(type, name, flags);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
28
|
export const ref = (path) => {
|
|
55
|
-
return
|
|
29
|
+
return parseReferenceTag(isArray(path) ? path[0] : path);
|
|
56
30
|
};
|
|
57
31
|
|
|
58
32
|
export const lit = (str) => buildLiteralTag(stripArray(str));
|
|
@@ -63,4 +37,4 @@ export const nodeOpen = buildOpenNodeTag;
|
|
|
63
37
|
export const fragOpen = buildOpenFragmentTag;
|
|
64
38
|
export const coverOpen = buildOpenCoverTag;
|
|
65
39
|
export const nodeClose = buildCloseNodeTag;
|
|
66
|
-
export const tree = (...tags) =>
|
|
40
|
+
export const tree = (...tags) => treeFromStream(tags);
|
package/lib/spans.js
CHANGED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { buildModule, defaultNodeSize } from '@bablr/btree/enhanceable';
|
|
2
|
-
|
|
3
|
-
const { isArray } = Array;
|
|
4
|
-
const { freeze } = Object;
|
|
5
|
-
|
|
6
|
-
export { defaultNodeSize };
|
|
7
|
-
|
|
8
|
-
const __getAtName = (name, sortedArray, startIdx = 0, endIdx = sortedArray.length - 1) => {
|
|
9
|
-
if (!sortedArray.length || endIdx < startIdx) return null;
|
|
10
|
-
|
|
11
|
-
let idx = startIdx + Math.floor((endIdx - startIdx) / 2 + 0.1);
|
|
12
|
-
let entry = sortedArray[idx];
|
|
13
|
-
let { 0: key, 1: value } = entry;
|
|
14
|
-
|
|
15
|
-
let direction = compareNames(name, key);
|
|
16
|
-
|
|
17
|
-
if (direction === 0) {
|
|
18
|
-
return value;
|
|
19
|
-
} else {
|
|
20
|
-
if (startIdx === endIdx) return null;
|
|
21
|
-
|
|
22
|
-
if (direction > 0) {
|
|
23
|
-
return __getAtName(name, sortedArray, idx + 1, endIdx);
|
|
24
|
-
} else {
|
|
25
|
-
return __getAtName(name, sortedArray, startIdx, idx - 1);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const getAtName = (name, sortedArray, startIdx = 0, endIdx = sortedArray.length - 1) => {
|
|
31
|
-
return __getAtName(name, sortedArray, startIdx, endIdx);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const compareNames = (a, b) => (a > b ? 1 : b > a ? -1 : 0);
|
|
35
|
-
|
|
36
|
-
export const sumValues = (values) => {
|
|
37
|
-
let mapStats = values.reduce(
|
|
38
|
-
(acc, val) => {
|
|
39
|
-
const { names } = acc;
|
|
40
|
-
if (isArray(val)) {
|
|
41
|
-
let arr = getSums(val).names;
|
|
42
|
-
let map = names;
|
|
43
|
-
|
|
44
|
-
for (const { 0: key, 1: value } of arr) {
|
|
45
|
-
let count = map.get(key)?.[1] ?? 0;
|
|
46
|
-
|
|
47
|
-
map.set(key, freeze([key, count + value]));
|
|
48
|
-
}
|
|
49
|
-
} else if (val) {
|
|
50
|
-
let span = val;
|
|
51
|
-
|
|
52
|
-
const { name } = span;
|
|
53
|
-
|
|
54
|
-
if (name) {
|
|
55
|
-
let count = names.get(name)?.[1] ?? 0;
|
|
56
|
-
|
|
57
|
-
names.set(name, freeze([name, count + 1]));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return acc;
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
names: new Map(),
|
|
64
|
-
},
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
let stats = {
|
|
68
|
-
names: [...mapStats.names.values()].sort((a, b) => compareNames(a[0], b[0])),
|
|
69
|
-
};
|
|
70
|
-
freeze(stats);
|
|
71
|
-
freeze(stats.names);
|
|
72
|
-
return stats;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const module_ = buildModule(defaultNodeSize, sumValues);
|
|
76
|
-
|
|
77
|
-
const {
|
|
78
|
-
from,
|
|
79
|
-
fromValues,
|
|
80
|
-
push,
|
|
81
|
-
pop,
|
|
82
|
-
addAt,
|
|
83
|
-
isValidNode,
|
|
84
|
-
assertValidNode,
|
|
85
|
-
getSize,
|
|
86
|
-
getValues,
|
|
87
|
-
getSums,
|
|
88
|
-
setValues,
|
|
89
|
-
traverse,
|
|
90
|
-
traverseInner,
|
|
91
|
-
findPath,
|
|
92
|
-
getAt,
|
|
93
|
-
replaceAt,
|
|
94
|
-
removeAt,
|
|
95
|
-
} = module_;
|
|
96
|
-
|
|
97
|
-
const getSpan = (name, spans) => {
|
|
98
|
-
let nameCount = 0;
|
|
99
|
-
let node = spans;
|
|
100
|
-
let idx = -1;
|
|
101
|
-
let index = getAtName(name, getSums(spans).names);
|
|
102
|
-
|
|
103
|
-
// drill into subtrees, passing over subtrees with too few references of the desired name
|
|
104
|
-
outer: while (node) {
|
|
105
|
-
let sums = getSums(node);
|
|
106
|
-
|
|
107
|
-
if (!sums) return null;
|
|
108
|
-
|
|
109
|
-
let valueNameCount = getAtName(name, sums.names);
|
|
110
|
-
|
|
111
|
-
if (nameCount + valueNameCount < index) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
for (const value of getValues(node)) {
|
|
116
|
-
if (!isArray(value)) {
|
|
117
|
-
idx++;
|
|
118
|
-
let span = value;
|
|
119
|
-
|
|
120
|
-
if (name != null && span.name === name) {
|
|
121
|
-
nameCount += 1;
|
|
122
|
-
if (nameCount === index) {
|
|
123
|
-
return getAt(idx, spans);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
} else {
|
|
127
|
-
let valueSums = getSums(value);
|
|
128
|
-
if (nameCount + getAtName(name, valueSums.names) > index) {
|
|
129
|
-
node = value;
|
|
130
|
-
continue outer;
|
|
131
|
-
} else {
|
|
132
|
-
nameCount += getAtName(name, valueSums.names) ?? 0;
|
|
133
|
-
idx += getSize(value);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return null;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
export {
|
|
145
|
-
from,
|
|
146
|
-
fromValues,
|
|
147
|
-
push,
|
|
148
|
-
pop,
|
|
149
|
-
addAt,
|
|
150
|
-
isValidNode,
|
|
151
|
-
assertValidNode,
|
|
152
|
-
getSize,
|
|
153
|
-
getValues,
|
|
154
|
-
getSums,
|
|
155
|
-
setValues,
|
|
156
|
-
traverse,
|
|
157
|
-
traverseInner,
|
|
158
|
-
findPath,
|
|
159
|
-
getAt,
|
|
160
|
-
replaceAt,
|
|
161
|
-
removeAt,
|
|
162
|
-
getSpan,
|
|
163
|
-
};
|