@agentshouse/mdmodel 0.1.0-ccf1367190878 → 0.1.0-cdbd463e01dc2

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.
Files changed (135) hide show
  1. package/API.md +197 -178
  2. package/README.md +21 -22
  3. package/dist/blocks.d.ts.map +1 -1
  4. package/dist/blocks.js +35 -20
  5. package/dist/definition.d.ts +3 -1
  6. package/dist/definition.d.ts.map +1 -1
  7. package/dist/definition.js +112 -24
  8. package/dist/divide.d.ts.map +1 -1
  9. package/dist/divide.js +27 -17
  10. package/dist/document.d.ts +5 -5
  11. package/dist/document.d.ts.map +1 -1
  12. package/dist/document.js +304 -187
  13. package/dist/event.d.ts +78 -0
  14. package/dist/event.d.ts.map +1 -0
  15. package/dist/event.js +230 -0
  16. package/dist/facts.d.ts +15 -0
  17. package/dist/facts.d.ts.map +1 -0
  18. package/dist/facts.js +39 -0
  19. package/dist/index.d.ts +22 -8
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +13 -6
  22. package/dist/kinds.d.ts +19 -0
  23. package/dist/kinds.d.ts.map +1 -0
  24. package/dist/kinds.js +161 -0
  25. package/dist/links.d.ts +2 -0
  26. package/dist/links.d.ts.map +1 -1
  27. package/dist/links.js +107 -50
  28. package/dist/paths.d.ts +9 -1
  29. package/dist/paths.d.ts.map +1 -1
  30. package/dist/paths.js +28 -2
  31. package/dist/pattern.d.ts +10 -0
  32. package/dist/pattern.d.ts.map +1 -0
  33. package/dist/pattern.js +355 -0
  34. package/dist/project.d.ts +1 -0
  35. package/dist/project.d.ts.map +1 -1
  36. package/dist/project.js +38 -15
  37. package/dist/query/language.d.ts +223 -0
  38. package/dist/query/language.d.ts.map +1 -0
  39. package/dist/query/language.js +565 -0
  40. package/dist/query/match.d.ts +14 -0
  41. package/dist/query/match.d.ts.map +1 -0
  42. package/dist/query/match.js +121 -0
  43. package/dist/query/rows.d.ts +32 -0
  44. package/dist/query/rows.d.ts.map +1 -0
  45. package/dist/query/rows.js +161 -0
  46. package/dist/query/sql.d.ts +39 -0
  47. package/dist/query/sql.d.ts.map +1 -0
  48. package/dist/query/sql.js +279 -0
  49. package/dist/references.d.ts.map +1 -1
  50. package/dist/references.js +6 -1
  51. package/dist/reserved.d.ts +5 -0
  52. package/dist/reserved.d.ts.map +1 -0
  53. package/dist/reserved.js +20 -0
  54. package/dist/schema.d.ts +1 -0
  55. package/dist/schema.d.ts.map +1 -1
  56. package/dist/schema.js +55 -4
  57. package/dist/types.d.ts +35 -4
  58. package/dist/types.d.ts.map +1 -1
  59. package/dist/validate.d.ts +29 -4
  60. package/dist/validate.d.ts.map +1 -1
  61. package/dist/validate.js +301 -85
  62. package/dist/yaml.d.ts.map +1 -1
  63. package/dist/yaml.js +36 -3
  64. package/fixtures/README.md +26 -6
  65. package/fixtures/cases/conditional-section/context.json +1 -0
  66. package/fixtures/cases/conditional-section/expected.json +6 -0
  67. package/fixtures/cases/conditional-section/library/questions/hosting.md +9 -0
  68. package/fixtures/cases/conditional-section/library/questions/payments.md +12 -0
  69. package/fixtures/cases/conditional-section/schema.yaml +14 -0
  70. package/fixtures/cases/cross-room-link/context.json +1 -0
  71. package/fixtures/cases/cross-room-link/expected.json +1 -0
  72. package/fixtures/cases/cross-room-link/library/clients/acme.md +6 -0
  73. package/fixtures/cases/cross-room-link/schema.yaml +3 -0
  74. package/fixtures/cases/cross-room-reference/context.json +1 -0
  75. package/fixtures/cases/cross-room-reference/expected.json +1 -0
  76. package/fixtures/cases/cross-room-reference/library/clients/acme.md +9 -0
  77. package/fixtures/cases/cross-room-reference/schema.yaml +9 -0
  78. package/fixtures/cases/link-into-a-reserved-name/context.json +1 -0
  79. package/fixtures/cases/link-into-a-reserved-name/expected.json +5 -0
  80. package/fixtures/cases/link-into-a-reserved-name/library/notes/a.md +6 -0
  81. package/fixtures/cases/link-into-a-reserved-name/schema.yaml +3 -0
  82. package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/context.json +1 -0
  83. package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/expected.json +5 -0
  84. package/fixtures/cases/link-into-a-reserved-name-from-an-untyped-document/library/notes/b.md +5 -0
  85. package/fixtures/cases/member-on-an-untyped-document/context.json +1 -0
  86. package/fixtures/cases/member-on-an-untyped-document/expected.json +6 -0
  87. package/fixtures/cases/member-on-an-untyped-document/library/note.md +4 -0
  88. package/fixtures/cases/member-on-another-type/context.json +1 -0
  89. package/fixtures/cases/member-on-another-type/expected.json +6 -0
  90. package/fixtures/cases/member-on-another-type/library/note.md +4 -0
  91. package/fixtures/cases/member-on-another-type/schema.yaml +7 -0
  92. package/fixtures/cases/reference-into-a-reserved-name/context.json +1 -0
  93. package/fixtures/cases/reference-into-a-reserved-name/expected.json +6 -0
  94. package/fixtures/cases/reference-into-a-reserved-name/library/notes/a.md +4 -0
  95. package/fixtures/cases/reference-into-a-reserved-name/library/settings/brief.md +1 -0
  96. package/fixtures/cases/reference-into-a-reserved-name/schema.yaml +3 -0
  97. package/fixtures/cases/room-md-declares-a-type/context.json +1 -0
  98. package/fixtures/cases/room-md-declares-a-type/expected.json +6 -0
  99. package/fixtures/cases/room-md-declares-a-type/library/ROOM.md +5 -0
  100. package/fixtures/cases/typed-path-names-another-type/context.json +11 -0
  101. package/fixtures/cases/typed-path-names-another-type/expected.json +6 -0
  102. package/fixtures/cases/typed-path-names-another-type/library/settings/prefs/one.md +3 -0
  103. package/fixtures/cases/typed-path-names-another-type/schema.yaml +6 -0
  104. package/fixtures/cases/typed-path-names-its-type/context.json +11 -0
  105. package/fixtures/cases/typed-path-names-its-type/expected.json +3 -0
  106. package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/deeper/two.md +1 -0
  107. package/fixtures/cases/typed-path-names-its-type/library/settings/prefs/one.md +4 -0
  108. package/fixtures/cases/typed-path-names-its-type/schema.yaml +6 -0
  109. package/fixtures/cases/typed-path-names-no-type/context.json +11 -0
  110. package/fixtures/cases/typed-path-names-no-type/expected.json +6 -0
  111. package/fixtures/cases/typed-path-names-no-type/library/settings/prefs/one.md +1 -0
  112. package/fixtures/cases/typed-path-names-no-type/schema.yaml +6 -0
  113. package/fixtures/cases/unnamed-typed-path-checks-its-fields/context.json +11 -0
  114. package/fixtures/cases/unnamed-typed-path-checks-its-fields/expected.json +6 -0
  115. package/fixtures/cases/unnamed-typed-path-checks-its-fields/library/rooms/team/tasks/plan.md +4 -0
  116. package/fixtures/cases/unnamed-typed-path-checks-its-fields/schema.yaml +5 -0
  117. package/fixtures/cases/unnamed-typed-path-names-a-type/context.json +11 -0
  118. package/fixtures/cases/unnamed-typed-path-names-a-type/expected.json +6 -0
  119. package/fixtures/cases/unnamed-typed-path-names-a-type/library/rooms/team/tasks/plan.md +6 -0
  120. package/fixtures/cases/unnamed-typed-path-names-a-type/schema.yaml +5 -0
  121. package/fixtures/cases/unnamed-typed-path-reads-its-type/context.json +11 -0
  122. package/fixtures/cases/unnamed-typed-path-reads-its-type/expected.json +3 -0
  123. package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/plan.md +1 -0
  124. package/fixtures/cases/unnamed-typed-path-reads-its-type/library/rooms/team/tasks/plan.md +5 -0
  125. package/fixtures/cases/unnamed-typed-path-reads-its-type/schema.yaml +5 -0
  126. package/fixtures/cases/unnamed-typed-path-without-a-body/context.json +11 -0
  127. package/fixtures/cases/unnamed-typed-path-without-a-body/expected.json +5 -0
  128. package/fixtures/cases/unnamed-typed-path-without-a-body/library/rooms/team/tasks/plan.md +5 -0
  129. package/fixtures/cases/unnamed-typed-path-without-a-body/schema.yaml +5 -0
  130. package/fixtures/division.json +26 -26
  131. package/fixtures/queries.json +913 -0
  132. package/package.json +7 -2
  133. package/dist/condition.d.ts +0 -149
  134. package/dist/condition.d.ts.map +0 -1
  135. package/dist/condition.js +0 -500
@@ -0,0 +1,121 @@
1
+ import { byCodePoint, instantKey } from '../kinds.js';
2
+ import { dirname } from '../paths.js';
3
+ import { invalid, } from './language.js';
4
+ import { indexed, placedOf } from './rows.js';
5
+ const BOUNDS = { gt: '>', gte: '>=', lt: '<', lte: '<=' };
6
+ function globbed(pattern) {
7
+ let source = '';
8
+ for (let at = 0; at < pattern.length; at += 1) {
9
+ const char = pattern[at];
10
+ if (char === '*')
11
+ source += '.*';
12
+ else if (char === '[') {
13
+ const end = pattern.indexOf(']', at);
14
+ source += pattern.slice(at, end + 1);
15
+ at = end;
16
+ }
17
+ else
18
+ source += char.replace(/[.\\^$+?()|{}/]/gu, '\\$&');
19
+ }
20
+ return new RegExp(`^${source}$`, 'u');
21
+ }
22
+ function reached(values, field) {
23
+ const { keys, places, glob } = placedOf(field, 'value');
24
+ const matched = glob ? globbed(places) : null;
25
+ return values.filter((row) => row.keys === keys && (matched === null ? row.places === places : matched.test(row.places)));
26
+ }
27
+ function holds(sign, operator) {
28
+ if (operator === '=')
29
+ return sign === 0;
30
+ if (operator === '>')
31
+ return sign > 0;
32
+ if (operator === '>=')
33
+ return sign >= 0;
34
+ if (operator === '<')
35
+ return sign < 0;
36
+ return sign <= 0;
37
+ }
38
+ function compares(row, operator, value) {
39
+ if (typeof value !== 'string') {
40
+ if (row.kind !== typeof value)
41
+ return false;
42
+ const right = typeof value === 'boolean' ? Number(value) : value;
43
+ return holds(Math.sign(row.value - right), operator);
44
+ }
45
+ if (row.instant !== null) {
46
+ const key = instantKey(value);
47
+ return key !== null && holds(byCodePoint(row.instant, key), operator);
48
+ }
49
+ return row.kind === 'string' && holds(byCodePoint(row.value, value), operator);
50
+ }
51
+ function same(row, value) {
52
+ return value === null ? row.kind === 'null' : compares(row, '=', value);
53
+ }
54
+ function itemsOf(values, held) {
55
+ return values.filter((row) => row.keys === held.keys && row.places === held.places && row.item >= 0);
56
+ }
57
+ function matching(values, held, wanted) {
58
+ return wanted.some((value) => same(held, value) ||
59
+ (held.kind === 'array' && itemsOf(values, held).some((item) => same(item, value))));
60
+ }
61
+ function tested(values, field, test) {
62
+ const rows = reached(values, field);
63
+ const present = rows.some((row) => row.item === -1);
64
+ if (test.op === 'exists')
65
+ return test.exists === present;
66
+ if (test.op === 'eq' || test.op === 'in') {
67
+ const wanted = test.op === 'eq' ? [test.value] : test.values;
68
+ return rows.some((row) => wanted.some((value) => same(row, value)));
69
+ }
70
+ if (test.op === 'ne' || test.op === 'nin') {
71
+ const wanted = test.op === 'ne' ? [test.value] : test.values;
72
+ return !present || rows.some((row) => row.item === -1 && !matching(values, row, wanted));
73
+ }
74
+ if (test.op === 'range') {
75
+ return rows.some((row) => row.item === -1 &&
76
+ test.bounds.every(([operator, bound]) => compares(row, BOUNDS[operator], bound)));
77
+ }
78
+ if (test.op === 'prefix') {
79
+ return rows.some((row) => row.kind === 'string' && row.value.startsWith(test.prefix));
80
+ }
81
+ if (test.op === 'all') {
82
+ return rows.some((row) => row.item === -1 &&
83
+ row.kind === 'array' &&
84
+ test.values.every((value) => itemsOf(values, row).some((item) => same(item, value))));
85
+ }
86
+ return rows.some((row) => row.item === -1 && row.kind === 'array' && row.size === test.size);
87
+ }
88
+ function conditioned(values, condition) {
89
+ if ('every' in condition)
90
+ return condition.every.every((one) => conditioned(values, one));
91
+ if ('some' in condition)
92
+ return condition.some.some((one) => conditioned(values, one));
93
+ return tested(values, condition.field, condition.test);
94
+ }
95
+ function scoped(candidate, values, scope) {
96
+ return ((scope.types === null || (candidate.type !== null && scope.types.includes(candidate.type))) &&
97
+ (scope.pathPrefix === null ||
98
+ scope.pathPrefix === '' ||
99
+ candidate.path.startsWith(`${scope.pathPrefix}/`)) &&
100
+ (scope.where === null || conditioned(values, scope.where)));
101
+ }
102
+ export function heldAt(candidate, field) {
103
+ return reached(indexed(candidate.path, candidate.fields, candidate.definition).values, field);
104
+ }
105
+ export function matches(plan, candidate) {
106
+ if (plan.rooms !== null)
107
+ invalid('rooms', 'names Rooms, which one Document does not choose');
108
+ if (plan.hop !== null)
109
+ invalid('hop', 'tests other Documents, which one Document cannot answer');
110
+ if (plan.backlinks !== null) {
111
+ invalid('backlinks', 'tests other Documents, which one Document cannot answer');
112
+ }
113
+ const values = indexed(candidate.path, candidate.fields, candidate.definition).values;
114
+ return ((plan.paths === null || plan.paths.includes(candidate.path)) &&
115
+ (plan.fileIds === null ||
116
+ (candidate.fileId !== null && plan.fileIds.includes(candidate.fileId))) &&
117
+ (plan.folder === null || dirname(candidate.path) === plan.folder) &&
118
+ scoped(candidate, values, plan.root) &&
119
+ (plan.text === null ||
120
+ (candidate.text !== null && candidate.text.toLowerCase().includes(plan.text.toLowerCase()))));
121
+ }
@@ -0,0 +1,32 @@
1
+ import { type Definition } from '../definition.js';
2
+ export type HeldKind = 'string' | 'number' | 'boolean' | 'null' | 'array' | 'object' | 'undefined';
3
+ export type HeldValue = {
4
+ readonly keys: string;
5
+ readonly places: string;
6
+ readonly item: number;
7
+ readonly kind: HeldKind;
8
+ readonly value: string | number | null;
9
+ readonly size: number | null;
10
+ readonly instant: string | null;
11
+ };
12
+ export type HeldLink = {
13
+ readonly kind: 'field';
14
+ readonly keys: string;
15
+ readonly places: string;
16
+ readonly target: string;
17
+ readonly field: string;
18
+ };
19
+ export type Indexed = {
20
+ readonly values: readonly HeldValue[];
21
+ readonly links: readonly HeldLink[];
22
+ };
23
+ export type Reach = 'exact' | 'value' | 'link';
24
+ export type Placed = {
25
+ readonly keys: string;
26
+ readonly places: string;
27
+ readonly glob: boolean;
28
+ };
29
+ export declare function placedOf(pointer: string, reach: Reach): Placed;
30
+ export declare function heldKind(value: unknown): HeldKind;
31
+ export declare function indexed(path: string, fields: Readonly<Record<string, unknown>>, definition: Pick<Definition, 'frontmatter'> | undefined): Indexed;
32
+ //# sourceMappingURL=rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/query/rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,UAAU,EAEhB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEnG,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/C,MAAM,MAAM,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAahG,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAuB9D;AA4BD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAMjD;AAoGD,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,SAAS,GACtD,OAAO,CAcT"}
@@ -0,0 +1,161 @@
1
+ import { ARRAY_INDEX, escapePointer, itemFacts, memberFacts, } from '../definition.js';
2
+ import { instantKey, kindOf } from '../kinds.js';
3
+ import { target } from '../paths.js';
4
+ export function placedOf(pointer, reach) {
5
+ const [first = '', ...rest] = pointer.split('/').slice(1);
6
+ const keys = [first];
7
+ const gaps = [[]];
8
+ for (const segment of rest) {
9
+ if (ARRAY_INDEX.test(segment)) {
10
+ gaps.at(-1).push(segment);
11
+ continue;
12
+ }
13
+ keys.push(segment);
14
+ gaps.push([]);
15
+ }
16
+ const places = gaps
17
+ .map((gap, at) => {
18
+ const open = at < gaps.length - 1 ? reach !== 'exact' : reach === 'link';
19
+ return `/${gap.map((number) => `[.:]${number}`).join('')}.${open ? '*' : ''}`;
20
+ })
21
+ .join('');
22
+ return {
23
+ keys: keys.map((key) => `/${key}`).join(''),
24
+ places,
25
+ glob: /[[*]/u.test(places),
26
+ };
27
+ }
28
+ function placesOf({ done, head, tail }) {
29
+ return `${done}/${head}${tail}.`;
30
+ }
31
+ function throughOf(keys, places) {
32
+ const gaps = places.split('/').slice(1);
33
+ return keys
34
+ .split('/')
35
+ .slice(1)
36
+ .map((key, at) => `/${key}${gaps[at].replace(/\.\d*/gu, '').replaceAll(':', '/')}`)
37
+ .join('');
38
+ }
39
+ function plainObject(value) {
40
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
41
+ }
42
+ function referred(facts, value) {
43
+ return typeof value === 'string' && facts?.reference !== undefined;
44
+ }
45
+ function resolved(reading, facts, value) {
46
+ if (!referred(facts, value))
47
+ return value;
48
+ return target(reading.path, value) ?? undefined;
49
+ }
50
+ export function heldKind(value) {
51
+ if (value === undefined)
52
+ return 'undefined';
53
+ if (value === null)
54
+ return 'null';
55
+ if (Array.isArray(value))
56
+ return 'array';
57
+ if (typeof value === 'object')
58
+ return 'object';
59
+ return typeof value;
60
+ }
61
+ function scalarOf(value) {
62
+ if (typeof value === 'string' || typeof value === 'number')
63
+ return value;
64
+ if (typeof value === 'boolean')
65
+ return value ? 1 : 0;
66
+ if (Array.isArray(value))
67
+ return JSON.stringify(value);
68
+ return null;
69
+ }
70
+ function instantOf(facts, value) {
71
+ return facts !== undefined && kindOf(facts) === 'date-time' ? instantKey(value) : null;
72
+ }
73
+ function held(reading, at, places, value, items) {
74
+ reading.values.push({
75
+ keys: at.keys,
76
+ places,
77
+ item: -1,
78
+ kind: heldKind(value),
79
+ value: scalarOf(value),
80
+ size: Array.isArray(value) ? value.length : null,
81
+ instant: instantOf(at.facts, value),
82
+ });
83
+ if (!Array.isArray(value))
84
+ return;
85
+ value.forEach((item, index) => {
86
+ const itemKind = heldKind(item);
87
+ reading.values.push({
88
+ keys: at.keys,
89
+ places,
90
+ item: index,
91
+ kind: itemKind,
92
+ value: itemKind === 'array' ? null : scalarOf(item),
93
+ size: null,
94
+ instant: instantOf(items[index], item),
95
+ });
96
+ });
97
+ }
98
+ function itemsOf(facts, node) {
99
+ return node.map((_, index) => (facts === undefined ? undefined : itemFacts(facts, index)));
100
+ }
101
+ function record(reading, node, at) {
102
+ const items = Array.isArray(node) ? itemsOf(at.facts, node) : [];
103
+ const value = Array.isArray(node)
104
+ ? node.map((item, index) => resolved(reading, items[index], item))
105
+ : resolved(reading, at.facts, node);
106
+ const places = placesOf(at);
107
+ held(reading, at, places, value, items);
108
+ if (typeof value !== 'string' || !referred(at.facts, node))
109
+ return;
110
+ reading.links.push({
111
+ kind: 'field',
112
+ keys: at.keys,
113
+ places,
114
+ target: value,
115
+ field: throughOf(at.keys, places),
116
+ });
117
+ }
118
+ function walk(reading, node, at) {
119
+ record(reading, node, at);
120
+ if (Array.isArray(node)) {
121
+ const items = itemsOf(at.facts, node);
122
+ node.forEach((item, index) => walk(reading, item, {
123
+ ...at,
124
+ tail: `${at.tail}.${index}`,
125
+ exact: `${at.exact}/${index}`,
126
+ facts: items[index],
127
+ }));
128
+ return;
129
+ }
130
+ if (!plainObject(node))
131
+ return;
132
+ for (const [key, value] of Object.entries(node)) {
133
+ const segment = escapePointer(key);
134
+ const exact = `${at.exact}/${segment}`;
135
+ const facts = at.facts === undefined ? undefined : memberFacts(at.facts, key);
136
+ walk(reading, value, ARRAY_INDEX.test(segment)
137
+ ? {
138
+ ...at,
139
+ head: `${at.head}${at.tail.replaceAll('.', ':')}:${segment}`,
140
+ tail: '',
141
+ exact,
142
+ facts,
143
+ }
144
+ : { keys: `${at.keys}/${segment}`, done: placesOf(at), head: '', tail: '', exact, facts });
145
+ }
146
+ }
147
+ export function indexed(path, fields, definition) {
148
+ const reading = { path, values: [], links: [] };
149
+ for (const [name, value] of Object.entries(fields)) {
150
+ const segment = escapePointer(name);
151
+ walk(reading, value, {
152
+ keys: `/${segment}`,
153
+ done: '',
154
+ head: '',
155
+ tail: '',
156
+ exact: `/${segment}`,
157
+ facts: definition === undefined ? undefined : memberFacts(definition.frontmatter, name),
158
+ });
159
+ }
160
+ return { values: reading.values, links: reading.links };
161
+ }
@@ -0,0 +1,39 @@
1
+ import { type Ordering } from '../kinds.js';
2
+ import type { QueryPlan, Scope } from './language.js';
3
+ import { type HeldValue, type Reach } from './rows.js';
4
+ export type SqlValue = string | number | bigint | Uint8Array | null;
5
+ export type Fragment = {
6
+ readonly sql: string;
7
+ readonly bind: readonly SqlValue[];
8
+ };
9
+ export type Collate = (ordering: Ordering, lists: boolean, total: boolean) => string | null;
10
+ export type Term = {
11
+ readonly ordering: Ordering;
12
+ readonly kind: Fragment;
13
+ readonly value: Fragment;
14
+ readonly instant?: Fragment;
15
+ readonly total?: boolean;
16
+ };
17
+ export type Following = {
18
+ readonly beyond: Fragment;
19
+ readonly equal: Fragment;
20
+ };
21
+ export declare const VALUE_TABLE = "CREATE TABLE replica_values (doc INTEGER NOT NULL, keys TEXT NOT NULL, places TEXT NOT NULL, item INTEGER NOT NULL, kind TEXT NOT NULL, value, size INTEGER, instant TEXT, PRIMARY KEY (doc, keys, places, item)) WITHOUT ROWID";
22
+ export declare const HOLDS_PHRASE = "holds_phrase";
23
+ export declare function holdsPhrase(_context: number, text: unknown, phrase: unknown): number;
24
+ export declare function fragment(sql: string, bind?: readonly SqlValue[]): Fragment;
25
+ export declare function joined(parts: readonly Fragment[], separator: string): Fragment;
26
+ export declare function all(parts: readonly Fragment[]): Fragment;
27
+ export declare function any(parts: readonly Fragment[]): Fragment;
28
+ export declare function grouped(part: Fragment): Fragment;
29
+ export declare function listed(values: readonly SqlValue[]): Fragment;
30
+ export declare function exists(part: Fragment): Fragment;
31
+ export declare function insertedValues(doc: number, values: readonly HeldValue[]): Fragment;
32
+ export declare function placed(alias: string, field: string, reach: Reach): Fragment;
33
+ export declare function scoped(alias: string, scope: Scope, byPaths?: boolean): Fragment;
34
+ export declare function tests(alias: string, plan: QueryPlan): Fragment;
35
+ export declare function sortValue(kind: SqlValue | undefined, value: unknown, instant: SqlValue | undefined): unknown;
36
+ export declare function sorted(collate: Collate, term: Term): Fragment;
37
+ export declare function beyond(collate: Collate, term: Term, value: unknown): Following;
38
+ export declare function following(parts: readonly Following[], tie: Fragment): Fragment;
39
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/query/sql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,279 @@
1
+ import { instantKey } from '../kinds.js';
2
+ import { placedOf } from './rows.js';
3
+ export const VALUE_TABLE = 'CREATE TABLE replica_values (doc INTEGER NOT NULL, keys TEXT NOT NULL, places TEXT NOT NULL, item INTEGER NOT NULL, kind TEXT NOT NULL, value, size INTEGER, instant TEXT, PRIMARY KEY (doc, keys, places, item)) WITHOUT ROWID';
4
+ export const HOLDS_PHRASE = 'holds_phrase';
5
+ const BOUNDS = { gt: '>', gte: '>=', lt: '<', lte: '<=' };
6
+ const NUMBERS = 1;
7
+ const INSTANTS = 2;
8
+ const TEXTS = 3;
9
+ const LISTS = 4;
10
+ export function holdsPhrase(_context, text, phrase) {
11
+ return typeof text === 'string' &&
12
+ typeof phrase === 'string' &&
13
+ text.toLowerCase().includes(phrase)
14
+ ? 1
15
+ : 0;
16
+ }
17
+ export function fragment(sql, bind = []) {
18
+ return { sql, bind };
19
+ }
20
+ export function joined(parts, separator) {
21
+ return {
22
+ sql: parts.map((part) => part.sql).join(separator),
23
+ bind: parts.flatMap((part) => part.bind),
24
+ };
25
+ }
26
+ function balanced(parts, separator) {
27
+ if (parts.length === 1)
28
+ return grouped(parts[0]);
29
+ const half = Math.ceil(parts.length / 2);
30
+ return grouped(joined([balanced(parts.slice(0, half), separator), balanced(parts.slice(half), separator)], separator));
31
+ }
32
+ export function all(parts) {
33
+ return parts.length === 0 ? fragment('1') : balanced(parts, ' AND ');
34
+ }
35
+ export function any(parts) {
36
+ return parts.length === 0 ? fragment('0') : balanced(parts, ' OR ');
37
+ }
38
+ export function grouped(part) {
39
+ return { sql: `(${part.sql})`, bind: part.bind };
40
+ }
41
+ export function listed(values) {
42
+ return fragment(`(${values.map(() => '?').join(', ')})`, values);
43
+ }
44
+ export function exists(part) {
45
+ return { sql: `EXISTS (${part.sql})`, bind: part.bind };
46
+ }
47
+ function not(part) {
48
+ return { sql: `NOT ${part.sql}`, bind: part.bind };
49
+ }
50
+ function scalarText(value) {
51
+ if (value === Infinity)
52
+ return 'Infinity';
53
+ if (value === -Infinity)
54
+ return '-Infinity';
55
+ return JSON.stringify(value);
56
+ }
57
+ export function insertedValues(doc, values) {
58
+ const rows = values.map((value) => `[${JSON.stringify(value.keys)},${JSON.stringify(value.places)},${value.item},${JSON.stringify(value.kind)},${scalarText(value.value)},${JSON.stringify(value.size)},${JSON.stringify(value.instant)}]`);
59
+ return fragment('INSERT INTO replica_values (doc, keys, places, item, kind, value, size, instant) SELECT ?, value ->> 0, value ->> 1, value ->> 2, value ->> 3, value ->> 4, value ->> 5, value ->> 6 FROM json_each(?)', [doc, `[${rows.join(',')}]`]);
60
+ }
61
+ export function placed(alias, field, reach) {
62
+ const { keys, places, glob } = placedOf(field, reach);
63
+ return fragment(`${alias}.keys = ? AND ${alias}.places ${glob ? 'GLOB' : '='} ?`, [keys, places]);
64
+ }
65
+ function plainText(alias, operator, text) {
66
+ return fragment(`${alias}.instant IS NULL AND ${alias}.kind = 'string' AND ${alias}.value ${operator} ?`, [text]);
67
+ }
68
+ function compares(alias, operator, value) {
69
+ if (typeof value !== 'string') {
70
+ return fragment(`${alias}.kind = ? AND ${alias}.value ${operator} ?`, [
71
+ typeof value,
72
+ typeof value === 'boolean' ? (value ? 1 : 0) : value,
73
+ ]);
74
+ }
75
+ const key = instantKey(value);
76
+ if (key === null)
77
+ return plainText(alias, operator, value);
78
+ return any([
79
+ fragment(`${alias}.instant IS NOT NULL AND ${alias}.instant ${operator} ?`, [key]),
80
+ plainText(alias, operator, value),
81
+ ]);
82
+ }
83
+ function same(alias, value) {
84
+ return value === null ? fragment(`${alias}.kind = 'null'`) : compares(alias, '=', value);
85
+ }
86
+ function heldValues(doc, field, alias, where) {
87
+ return joined([
88
+ fragment(`SELECT 1 FROM replica_values ${alias} WHERE ${alias}.doc = ${doc}.id AND `),
89
+ grouped(placed(alias, field, 'value')),
90
+ fragment(' AND '),
91
+ grouped(where),
92
+ ], '');
93
+ }
94
+ function itemOf(held, where) {
95
+ return exists(joined([
96
+ fragment(`SELECT 1 FROM replica_values i WHERE i.doc = ${held}.doc AND i.keys = ${held}.keys AND i.places = ${held}.places AND i.item >= 0 AND `),
97
+ grouped(where),
98
+ ], ''));
99
+ }
100
+ function matching(held, values) {
101
+ return any(values.map((value) => any([
102
+ same(held, value),
103
+ all([fragment(`${held}.kind = 'array'`), itemOf(held, same('i', value))]),
104
+ ])));
105
+ }
106
+ function tested(doc, field, test) {
107
+ const reached = exists(heldValues(doc, field, 'r', fragment('r.item = -1')));
108
+ if (test.op === 'exists')
109
+ return test.exists ? reached : not(reached);
110
+ if (test.op === 'eq' || test.op === 'in') {
111
+ const values = test.op === 'eq' ? [test.value] : test.values;
112
+ return exists(heldValues(doc, field, 'v', any(values.map((value) => same('v', value)))));
113
+ }
114
+ if (test.op === 'ne' || test.op === 'nin') {
115
+ const values = test.op === 'ne' ? [test.value] : test.values;
116
+ return any([
117
+ not(reached),
118
+ exists(heldValues(doc, field, 'h', all([fragment('h.item = -1'), not(grouped(matching('h', values)))]))),
119
+ ]);
120
+ }
121
+ if (test.op === 'range') {
122
+ return exists(heldValues(doc, field, 'v', all([
123
+ fragment('v.item = -1'),
124
+ ...test.bounds.map(([operator, bound]) => compares('v', BOUNDS[operator], bound)),
125
+ ])));
126
+ }
127
+ if (test.op === 'prefix') {
128
+ return exists(heldValues(doc, field, 'v', fragment("v.kind = 'string' AND substr(v.value, 1, length(?)) = ?", [
129
+ test.prefix,
130
+ test.prefix,
131
+ ])));
132
+ }
133
+ if (test.op === 'all') {
134
+ return exists(heldValues(doc, field, 'h', all([
135
+ fragment("h.item = -1 AND h.kind = 'array'"),
136
+ ...test.values.map((value) => itemOf('h', same('i', value))),
137
+ ])));
138
+ }
139
+ return exists(heldValues(doc, field, 'v', fragment("v.item = -1 AND v.kind = 'array' AND v.size = ?", [test.size])));
140
+ }
141
+ function conditioned(doc, condition) {
142
+ if ('every' in condition)
143
+ return all(condition.every.map((one) => conditioned(doc, one)));
144
+ if ('some' in condition)
145
+ return any(condition.some.map((one) => conditioned(doc, one)));
146
+ return tested(doc, condition.field, condition.test);
147
+ }
148
+ export function scoped(alias, scope, byPaths = false) {
149
+ const type = byPaths ? `+${alias}.type` : `${alias}.type`;
150
+ return all([
151
+ ...(scope.types === null
152
+ ? []
153
+ : [fragment(`${type} IN ${listed(scope.types).sql}`, scope.types)]),
154
+ ...(scope.pathPrefix === null || scope.pathPrefix === ''
155
+ ? []
156
+ : [
157
+ fragment(`${alias}.path >= ? AND ${alias}.path < ?`, [
158
+ `${scope.pathPrefix}/`,
159
+ `${scope.pathPrefix}0`,
160
+ ]),
161
+ ]),
162
+ ...(scope.where === null ? [] : [conditioned(alias, scope.where)]),
163
+ ]);
164
+ }
165
+ export function tests(alias, plan) {
166
+ return all([
167
+ ...(plan.paths === null
168
+ ? []
169
+ : [fragment(`${alias}.path IN ${listed(plan.paths).sql}`, plan.paths)]),
170
+ ...(plan.fileIds === null
171
+ ? []
172
+ : [fragment(`${alias}.file_id IN ${listed(plan.fileIds).sql}`, plan.fileIds)]),
173
+ ...(plan.folder === null ? [] : [fragment(`${alias}.folder = ?`, [plan.folder])]),
174
+ scoped(alias, plan.root, plan.paths !== null),
175
+ ...(plan.text === null
176
+ ? []
177
+ : [fragment(`${HOLDS_PHRASE}(${alias}.content, ?)`, [plan.text.toLowerCase()])]),
178
+ ]);
179
+ }
180
+ function instantMark(value) {
181
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
182
+ return null;
183
+ const { instant } = value;
184
+ return typeof instant === 'string' && Object.keys(value).length === 1 ? instant : null;
185
+ }
186
+ export function sortValue(kind, value, instant) {
187
+ return typeof instant === 'string' && kind === 'string' ? { instant } : value;
188
+ }
189
+ function classOf(value, ordering) {
190
+ if (value === null || value === undefined) {
191
+ return { placement: ordering.nulls === 'first' ? 0 : 2, klass: 0, scalar: null };
192
+ }
193
+ const mark = instantMark(value);
194
+ if (mark !== null)
195
+ return { placement: 1, klass: INSTANTS, scalar: mark };
196
+ if (typeof value === 'boolean')
197
+ return { placement: 1, klass: NUMBERS, scalar: value ? 1 : 0 };
198
+ if (typeof value === 'number')
199
+ return { placement: 1, klass: NUMBERS, scalar: value };
200
+ if (typeof value === 'string')
201
+ return { placement: 1, klass: TEXTS, scalar: value };
202
+ return { placement: 1, klass: LISTS, scalar: JSON.stringify(value) };
203
+ }
204
+ function placement(term) {
205
+ const nulls = term.ordering.nulls === 'first' ? 0 : 2;
206
+ return fragment(`CASE WHEN ${term.kind.sql} IS NULL OR ${term.kind.sql} = 'null' THEN ${nulls} ELSE 1 END`, [...term.kind.bind, ...term.kind.bind]);
207
+ }
208
+ function klass(term) {
209
+ const kinds = fragment(`CASE ${term.kind.sql} WHEN 'boolean' THEN ${NUMBERS} WHEN 'number' THEN ${NUMBERS} WHEN 'string' THEN ${TEXTS} WHEN 'array' THEN ${LISTS} ELSE 5 END`, term.kind.bind);
210
+ if (term.instant === undefined)
211
+ return kinds;
212
+ return fragment(`CASE WHEN ${term.instant.sql} IS NOT NULL THEN ${INSTANTS} ELSE ${kinds.sql} END`, [...term.instant.bind, ...kinds.bind]);
213
+ }
214
+ function classed(term, which) {
215
+ if (which === INSTANTS)
216
+ return term.instant ?? fragment('NULL');
217
+ const kinds = which === NUMBERS ? "('boolean', 'number')" : which === TEXTS ? "('string')" : "('array')";
218
+ const plain = which === TEXTS && term.instant !== undefined
219
+ ? fragment(` AND ${term.instant.sql} IS NULL`, term.instant.bind)
220
+ : fragment('');
221
+ return fragment(`(CASE WHEN ${term.kind.sql} IN ${kinds}${plain.sql} THEN ${term.value.sql} END)`, [...term.kind.bind, ...plain.bind, ...term.value.bind]);
222
+ }
223
+ function collated(collate, term, which) {
224
+ if (which === NUMBERS || which === INSTANTS)
225
+ return '';
226
+ const name = collate(term.ordering, which === LISTS, term.total === true);
227
+ return name === null ? '' : ` COLLATE ${name}`;
228
+ }
229
+ export function sorted(collate, term) {
230
+ const direction = term.ordering.direction === 'desc' ? 'DESC' : 'ASC';
231
+ return joined([
232
+ placement(term),
233
+ fragment(`${klass(term).sql} ${direction}`, klass(term).bind),
234
+ ...[NUMBERS, INSTANTS, TEXTS, LISTS].map((which) => {
235
+ const value = classed(term, which);
236
+ return fragment(`${value.sql}${collated(collate, term, which)} ${direction}`, value.bind);
237
+ }),
238
+ ], ', ');
239
+ }
240
+ export function beyond(collate, term, value) {
241
+ const held = classOf(value, term.ordering);
242
+ const place = placement(term);
243
+ if (held.placement !== 1) {
244
+ return {
245
+ beyond: fragment(`${place.sql} > ${held.placement}`, place.bind),
246
+ equal: fragment(`${place.sql} = ${held.placement}`, place.bind),
247
+ };
248
+ }
249
+ const after = term.ordering.direction === 'desc' ? '<' : '>';
250
+ const kind = klass(term);
251
+ const scalar = classed(term, held.klass);
252
+ const collation = collated(collate, term, held.klass);
253
+ return {
254
+ beyond: any([
255
+ fragment(`${place.sql} > 1`, place.bind),
256
+ all([
257
+ fragment(`${place.sql} = 1`, place.bind),
258
+ any([
259
+ fragment(`${kind.sql} ${after} ${held.klass}`, kind.bind),
260
+ all([
261
+ fragment(`${kind.sql} = ${held.klass}`, kind.bind),
262
+ fragment(`${scalar.sql} ${after} ?${collation}`, [...scalar.bind, held.scalar]),
263
+ ]),
264
+ ]),
265
+ ]),
266
+ ]),
267
+ equal: all([
268
+ fragment(`${place.sql} = 1 AND ${kind.sql} = ${held.klass}`, [...place.bind, ...kind.bind]),
269
+ fragment(`${scalar.sql} = ?${collation}`, [...scalar.bind, held.scalar]),
270
+ ]),
271
+ };
272
+ }
273
+ export function following(parts, tie) {
274
+ let condition = tie;
275
+ for (const part of [...parts].reverse()) {
276
+ condition = any([part.beyond, all([part.equal, condition])]);
277
+ }
278
+ return condition;
279
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAwBzD,wBAAgB,UAAU,CACxB,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,SAAS,SAAS,EAAE,CAItB"}
1
+ {"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA8BzD,wBAAgB,UAAU,CACxB,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,SAAS,SAAS,EAAE,CAItB"}
@@ -5,7 +5,12 @@ function collect(value, facts, pointer, found) {
5
5
  return;
6
6
  if (typeof value === 'string') {
7
7
  if (facts.reference !== undefined)
8
- found.push({ pointer, value, to: facts.reference });
8
+ found.push({
9
+ pointer,
10
+ value,
11
+ to: facts.reference,
12
+ ...(facts.crossRoom === true ? { crossRoom: true } : {}),
13
+ });
9
14
  return;
10
15
  }
11
16
  if (Array.isArray(value)) {
@@ -0,0 +1,5 @@
1
+ export declare const ROOM_DESCRIPTION = "ROOM.md";
2
+ export declare const RESERVED_NAMES: readonly string[];
3
+ export declare function isReservedName(name: string): boolean;
4
+ export declare function isDocumentPath(path: string): boolean;
5
+ //# sourceMappingURL=reserved.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reserved.d.ts","sourceRoot":"","sources":["../src/reserved.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAO3C,CAAC;AAQF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGpD"}