@bablr/agast-helpers 0.10.9 → 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/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 { referenceFlags } from './builders.js';
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 = attributes && printObject(attributes);
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 path
61
- .map((segment) => {
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 { segments } = binding;
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
- export const printReferenceFlags = (flags = referenceFlags) => {
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
- path.map((name) => freeze({ type: null, name })),
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?.type];
297
+ let printer = printers[tag.type];
298
+
299
+ return printer ? printer(tag) : tag;
300
+ };
285
301
 
286
- return printer(tag);
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 { freeze } from './object.js';
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 parseReference(isArray(path) ? path[0] : path);
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) => treeFromStreamSync(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
- };