@ifc-lite/rules 0.2.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.
Files changed (179) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +45 -0
  3. package/dist/engine/rule-engine-chunk.d.ts +25 -0
  4. package/dist/engine/rule-engine-chunk.d.ts.map +1 -0
  5. package/dist/engine/rule-engine-chunk.js +43 -0
  6. package/dist/engine/rule-engine-chunk.js.map +1 -0
  7. package/dist/engine/rule-engine-compare.d.ts +17 -0
  8. package/dist/engine/rule-engine-compare.d.ts.map +1 -0
  9. package/dist/engine/rule-engine-compare.js +69 -0
  10. package/dist/engine/rule-engine-compare.js.map +1 -0
  11. package/dist/engine/rule-engine-requirements.d.ts +37 -0
  12. package/dist/engine/rule-engine-requirements.d.ts.map +1 -0
  13. package/dist/engine/rule-engine-requirements.js +293 -0
  14. package/dist/engine/rule-engine-requirements.js.map +1 -0
  15. package/dist/engine/rule-engine-sets.d.ts +46 -0
  16. package/dist/engine/rule-engine-sets.d.ts.map +1 -0
  17. package/dist/engine/rule-engine-sets.js +298 -0
  18. package/dist/engine/rule-engine-sets.js.map +1 -0
  19. package/dist/engine/rule-engine-unit.d.ts +23 -0
  20. package/dist/engine/rule-engine-unit.d.ts.map +1 -0
  21. package/dist/engine/rule-engine-unit.js +64 -0
  22. package/dist/engine/rule-engine-unit.js.map +1 -0
  23. package/dist/engine/rule-engine.d.ts +29 -0
  24. package/dist/engine/rule-engine.d.ts.map +1 -0
  25. package/dist/engine/rule-engine.js +244 -0
  26. package/dist/engine/rule-engine.js.map +1 -0
  27. package/dist/filter/effective-filter-fields.d.ts +13 -0
  28. package/dist/filter/effective-filter-fields.d.ts.map +1 -0
  29. package/dist/filter/effective-filter-fields.js +44 -0
  30. package/dist/filter/effective-filter-fields.js.map +1 -0
  31. package/dist/filter/entity-predefined-type.d.ts +24 -0
  32. package/dist/filter/entity-predefined-type.d.ts.map +1 -0
  33. package/dist/filter/entity-predefined-type.js +34 -0
  34. package/dist/filter/entity-predefined-type.js.map +1 -0
  35. package/dist/filter/filter-evaluate-groups.d.ts +36 -0
  36. package/dist/filter/filter-evaluate-groups.d.ts.map +1 -0
  37. package/dist/filter/filter-evaluate-groups.js +111 -0
  38. package/dist/filter/filter-evaluate-groups.js.map +1 -0
  39. package/dist/filter/filter-evaluate-model-tag.d.ts +22 -0
  40. package/dist/filter/filter-evaluate-model-tag.d.ts.map +1 -0
  41. package/dist/filter/filter-evaluate-model-tag.js +35 -0
  42. package/dist/filter/filter-evaluate-model-tag.js.map +1 -0
  43. package/dist/filter/filter-evaluate-mutations.d.ts +51 -0
  44. package/dist/filter/filter-evaluate-mutations.d.ts.map +1 -0
  45. package/dist/filter/filter-evaluate-mutations.js +111 -0
  46. package/dist/filter/filter-evaluate-mutations.js.map +1 -0
  47. package/dist/filter/filter-evaluate-yield.d.ts +9 -0
  48. package/dist/filter/filter-evaluate-yield.d.ts.map +1 -0
  49. package/dist/filter/filter-evaluate-yield.js +32 -0
  50. package/dist/filter/filter-evaluate-yield.js.map +1 -0
  51. package/dist/filter/filter-evaluate.d.ts +120 -0
  52. package/dist/filter/filter-evaluate.d.ts.map +1 -0
  53. package/dist/filter/filter-evaluate.js +408 -0
  54. package/dist/filter/filter-evaluate.js.map +1 -0
  55. package/dist/filter/filter-group-rule.d.ts +23 -0
  56. package/dist/filter/filter-group-rule.d.ts.map +1 -0
  57. package/dist/filter/filter-group-rule.js +69 -0
  58. package/dist/filter/filter-group-rule.js.map +1 -0
  59. package/dist/filter/filter-groups.d.ts +65 -0
  60. package/dist/filter/filter-groups.d.ts.map +1 -0
  61. package/dist/filter/filter-groups.js +136 -0
  62. package/dist/filter/filter-groups.js.map +1 -0
  63. package/dist/filter/filter-iteration-source.d.ts +26 -0
  64. package/dist/filter/filter-iteration-source.d.ts.map +1 -0
  65. package/dist/filter/filter-iteration-source.js +154 -0
  66. package/dist/filter/filter-iteration-source.js.map +1 -0
  67. package/dist/filter/filter-iteration.d.ts +5 -0
  68. package/dist/filter/filter-iteration.d.ts.map +1 -0
  69. package/dist/filter/filter-iteration.js +25 -0
  70. package/dist/filter/filter-iteration.js.map +1 -0
  71. package/dist/filter/filter-match.d.ts +114 -0
  72. package/dist/filter/filter-match.d.ts.map +1 -0
  73. package/dist/filter/filter-match.js +302 -0
  74. package/dist/filter/filter-match.js.map +1 -0
  75. package/dist/filter/filter-ops.d.ts +90 -0
  76. package/dist/filter/filter-ops.d.ts.map +1 -0
  77. package/dist/filter/filter-ops.js +202 -0
  78. package/dist/filter/filter-ops.js.map +1 -0
  79. package/dist/filter/filter-rule-guards.d.ts +4 -0
  80. package/dist/filter/filter-rule-guards.d.ts.map +1 -0
  81. package/dist/filter/filter-rule-guards.js +74 -0
  82. package/dist/filter/filter-rule-guards.js.map +1 -0
  83. package/dist/filter/filter-rules.d.ts +275 -0
  84. package/dist/filter/filter-rules.d.ts.map +1 -0
  85. package/dist/filter/filter-rules.js +68 -0
  86. package/dist/filter/filter-rules.js.map +1 -0
  87. package/dist/filter/lens-material-names.d.ts +13 -0
  88. package/dist/filter/lens-material-names.d.ts.map +1 -0
  89. package/dist/filter/lens-material-names.js +36 -0
  90. package/dist/filter/lens-material-names.js.map +1 -0
  91. package/dist/filter/measure-units.d.ts +29 -0
  92. package/dist/filter/measure-units.d.ts.map +1 -0
  93. package/dist/filter/measure-units.js +72 -0
  94. package/dist/filter/measure-units.js.map +1 -0
  95. package/dist/filter/model-tag.d.ts +65 -0
  96. package/dist/filter/model-tag.d.ts.map +1 -0
  97. package/dist/filter/model-tag.js +57 -0
  98. package/dist/filter/model-tag.js.map +1 -0
  99. package/dist/filter/read-measure-subject.d.ts +28 -0
  100. package/dist/filter/read-measure-subject.d.ts.map +1 -0
  101. package/dist/filter/read-measure-subject.js +116 -0
  102. package/dist/filter/read-measure-subject.js.map +1 -0
  103. package/dist/filter/read-subject.d.ts +72 -0
  104. package/dist/filter/read-subject.d.ts.map +1 -0
  105. package/dist/filter/read-subject.js +128 -0
  106. package/dist/filter/read-subject.js.map +1 -0
  107. package/dist/filter/subject-match.d.ts +27 -0
  108. package/dist/filter/subject-match.d.ts.map +1 -0
  109. package/dist/filter/subject-match.js +52 -0
  110. package/dist/filter/subject-match.js.map +1 -0
  111. package/dist/filter/subject-read-options.d.ts +33 -0
  112. package/dist/filter/subject-read-options.d.ts.map +1 -0
  113. package/dist/filter/subject-read-options.js +8 -0
  114. package/dist/filter/subject-read-options.js.map +1 -0
  115. package/dist/ids/ids-facet-to-rules.d.ts +20 -0
  116. package/dist/ids/ids-facet-to-rules.d.ts.map +1 -0
  117. package/dist/ids/ids-facet-to-rules.js +230 -0
  118. package/dist/ids/ids-facet-to-rules.js.map +1 -0
  119. package/dist/ids/ids-regex.d.ts +44 -0
  120. package/dist/ids/ids-regex.d.ts.map +1 -0
  121. package/dist/ids/ids-regex.js +334 -0
  122. package/dist/ids/ids-regex.js.map +1 -0
  123. package/dist/ids/ids-to-rule-set.d.ts +39 -0
  124. package/dist/ids/ids-to-rule-set.d.ts.map +1 -0
  125. package/dist/ids/ids-to-rule-set.js +103 -0
  126. package/dist/ids/ids-to-rule-set.js.map +1 -0
  127. package/dist/ids/ids-xml-writer.d.ts +11 -0
  128. package/dist/ids/ids-xml-writer.d.ts.map +1 -0
  129. package/dist/ids/ids-xml-writer.js +172 -0
  130. package/dist/ids/ids-xml-writer.js.map +1 -0
  131. package/dist/ids/rule-set-to-ids.d.ts +45 -0
  132. package/dist/ids/rule-set-to-ids.d.ts.map +1 -0
  133. package/dist/ids/rule-set-to-ids.js +140 -0
  134. package/dist/ids/rule-set-to-ids.js.map +1 -0
  135. package/dist/ids/rule-to-ids-facets.d.ts +52 -0
  136. package/dist/ids/rule-to-ids-facets.d.ts.map +1 -0
  137. package/dist/ids/rule-to-ids-facets.js +291 -0
  138. package/dist/ids/rule-to-ids-facets.js.map +1 -0
  139. package/dist/ids/stored-unit-scale.d.ts +15 -0
  140. package/dist/ids/stored-unit-scale.d.ts.map +1 -0
  141. package/dist/ids/stored-unit-scale.js +64 -0
  142. package/dist/ids/stored-unit-scale.js.map +1 -0
  143. package/dist/index.d.ts +39 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +46 -0
  146. package/dist/index.js.map +1 -0
  147. package/dist/rule-set/between-chip.d.ts +54 -0
  148. package/dist/rule-set/between-chip.d.ts.map +1 -0
  149. package/dist/rule-set/between-chip.js +95 -0
  150. package/dist/rule-set/between-chip.js.map +1 -0
  151. package/dist/rule-set/requirement-invariants.d.ts +25 -0
  152. package/dist/rule-set/requirement-invariants.d.ts.map +1 -0
  153. package/dist/rule-set/requirement-invariants.js +29 -0
  154. package/dist/rule-set/requirement-invariants.js.map +1 -0
  155. package/dist/rule-set/requirement-text.d.ts +20 -0
  156. package/dist/rule-set/requirement-text.d.ts.map +1 -0
  157. package/dist/rule-set/requirement-text.js +179 -0
  158. package/dist/rule-set/requirement-text.js.map +1 -0
  159. package/dist/rule-set/rule-set-io-requirement.d.ts +22 -0
  160. package/dist/rule-set/rule-set-io-requirement.d.ts.map +1 -0
  161. package/dist/rule-set/rule-set-io-requirement.js +140 -0
  162. package/dist/rule-set/rule-set-io-requirement.js.map +1 -0
  163. package/dist/rule-set/rule-set-io-shared.d.ts +24 -0
  164. package/dist/rule-set/rule-set-io-shared.d.ts.map +1 -0
  165. package/dist/rule-set/rule-set-io-shared.js +48 -0
  166. package/dist/rule-set/rule-set-io-shared.js.map +1 -0
  167. package/dist/rule-set/rule-set-io-subject.d.ts +10 -0
  168. package/dist/rule-set/rule-set-io-subject.d.ts.map +1 -0
  169. package/dist/rule-set/rule-set-io-subject.js +67 -0
  170. package/dist/rule-set/rule-set-io-subject.js.map +1 -0
  171. package/dist/rule-set/rule-set-io.d.ts +37 -0
  172. package/dist/rule-set/rule-set-io.d.ts.map +1 -0
  173. package/dist/rule-set/rule-set-io.js +142 -0
  174. package/dist/rule-set/rule-set-io.js.map +1 -0
  175. package/dist/rule-set/rule-set.d.ts +109 -0
  176. package/dist/rule-set/rule-set.d.ts.map +1 -0
  177. package/dist/rule-set/rule-set.js +5 -0
  178. package/dist/rule-set/rule-set.js.map +1 -0
  179. package/package.json +59 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Live-edit overlay for `filter-evaluate.ts`'s property/quantity/attribute
3
+ * readers (#4946 review finding on PR #4984): split out of the evaluator
4
+ * itself so it stays inside its module-size budget.
5
+ *
6
+ * `evaluatorModelsFromState` (`lib/model-tags/evaluator-models.ts`) is the
7
+ * ONE place a model's live `MutablePropertyView` reaches the evaluator; this
8
+ * is the ONE place that overlay gets applied to what a rule reads, so a
9
+ * selector run right after an edit matches the edited value, not the file —
10
+ * on the occurrence AND on its defining TYPE object (`typePropertySetsFor`).
11
+ * A `type=` rule's own type-Name lookup and DELETE-suppression on a
12
+ * TYPE-inherited property (`mergeInheritedPropertySets` has no delete
13
+ * concept) remain base-store-only; both are follow-up scope.
14
+ */
15
+ import { extractPropertiesOnDemand, extractQuantitiesOnDemand, type IfcDataStore } from '@ifc-lite/parser';
16
+ import type { MutablePropertyView } from '@ifc-lite/mutations';
17
+ import type { AttrRows } from './filter-match.js';
18
+ type PsetSets = ReturnType<typeof extractPropertiesOnDemand>;
19
+ /** The occurrence's own property sets, WITH mutations applied when a
20
+ * `mutationView` is present — the same call `element-field-reader.ts`'s
21
+ * `setsFor` makes for the Elements chart's own field column. */
22
+ export declare function ownPropertySetsFor(store: IfcDataStore, expressId: number, mutationView: MutablePropertyView | undefined): PsetSets;
23
+ /** `typeBasePsets` (the defining TYPE object's own property sets, as
24
+ * `getInheritedTypePsets` in filter-evaluate.ts already resolves them —
25
+ * the type-specific on-demand path, not `ownPropertySetsFor`, since a
26
+ * type object walks a different relation than an occurrence) topped up
27
+ * with the mutation view's edit of that TYPE, when it has one — an
28
+ * edited pset replaces its base counterpart by name, an untouched one
29
+ * passes through. Same overlay `element-field-reader.ts`'s `typeSetsFor`
30
+ * applies for the Elements chart's own field column (#4946 review). */
31
+ export declare function typePropertySetsFor(typeBasePsets: PsetSets, typeId: number, mutationView: MutablePropertyView | undefined): PsetSets;
32
+ type QtySets = ReturnType<typeof extractQuantitiesOnDemand>;
33
+ /** The occurrence's quantity sets, WITH mutations applied when present. A
34
+ * `mutationView` built for a server-hydrated store (no quantity extractor,
35
+ * `!hasQuantityBase()`) answers `getQuantitiesForEntity` from its overlay
36
+ * ALONE, which would otherwise make an edited quantity's siblings — or an
37
+ * untouched quantity set — vanish from a selector's reads; merge the base
38
+ * back in for that case instead of trusting the overlay as the whole set. */
39
+ export declare function quantitySetsFor(store: IfcDataStore, expressId: number, mutationView: MutablePropertyView | undefined): QtySets;
40
+ /** The occurrence's root attributes, an edited one overriding its base value
41
+ * by name (order otherwise kept) — same merge `element-field-reader.ts`'s
42
+ * `attrsFor` does. */
43
+ export declare function attributesFor(store: IfcDataStore, expressId: number, mutationView: MutablePropertyView | undefined): AttrRows;
44
+ /** An edited value for ONE root attribute (#4946 review), for the two rule
45
+ * kinds that read a dedicated fast-path column instead of `attributesFor`'s
46
+ * full merge: `name` (`ctx.table.getNameOrUndefined`) and `predefinedType`
47
+ * (`resolveEntityPredefinedType`). `undefined` means "no edit" — the caller
48
+ * falls through to its base read, same as an unedited `attributesFor` row. */
49
+ export declare function mutatedAttributeValue(mutationView: MutablePropertyView | undefined, expressId: number, attrName: string): string | undefined;
50
+ export {};
51
+ //# sourceMappingURL=filter-evaluate-mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-evaluate-mutations.d.ts","sourceRoot":"","sources":["../../src/filter/filter-evaluate-mutations.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAA8B,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACvI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGlD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE7D;;iEAEiE;AACjE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,SAAS,GAAG,QAAQ,CAElI;AAED;;;;;;;wEAOwE;AACxE,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,SAAS,GAAG,QAAQ,CAMpI;AAED,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAqB5D;;;;;8EAK8E;AAC9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAM9H;AAED;;uBAEuB;AACvB,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,mBAAmB,GAAG,SAAS,GAAG,QAAQ,CAgB7H;AAED;;;;+EAI+E;AAC/E,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,mBAAmB,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5I"}
@@ -0,0 +1,111 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /**
5
+ * Live-edit overlay for `filter-evaluate.ts`'s property/quantity/attribute
6
+ * readers (#4946 review finding on PR #4984): split out of the evaluator
7
+ * itself so it stays inside its module-size budget.
8
+ *
9
+ * `evaluatorModelsFromState` (`lib/model-tags/evaluator-models.ts`) is the
10
+ * ONE place a model's live `MutablePropertyView` reaches the evaluator; this
11
+ * is the ONE place that overlay gets applied to what a rule reads, so a
12
+ * selector run right after an edit matches the edited value, not the file —
13
+ * on the occurrence AND on its defining TYPE object (`typePropertySetsFor`).
14
+ * A `type=` rule's own type-Name lookup and DELETE-suppression on a
15
+ * TYPE-inherited property (`mergeInheritedPropertySets` has no delete
16
+ * concept) remain base-store-only; both are follow-up scope.
17
+ */
18
+ import { extractPropertiesOnDemand, extractQuantitiesOnDemand, extractAllEntityAttributes } from '@ifc-lite/parser';
19
+ import { createdFilterRecord } from './effective-filter-fields.js';
20
+ /** The occurrence's own property sets, WITH mutations applied when a
21
+ * `mutationView` is present — the same call `element-field-reader.ts`'s
22
+ * `setsFor` makes for the Elements chart's own field column. */
23
+ export function ownPropertySetsFor(store, expressId, mutationView) {
24
+ return mutationView ? mutationView.getForEntity(expressId) : extractPropertiesOnDemand(store, expressId);
25
+ }
26
+ /** `typeBasePsets` (the defining TYPE object's own property sets, as
27
+ * `getInheritedTypePsets` in filter-evaluate.ts already resolves them —
28
+ * the type-specific on-demand path, not `ownPropertySetsFor`, since a
29
+ * type object walks a different relation than an occurrence) topped up
30
+ * with the mutation view's edit of that TYPE, when it has one — an
31
+ * edited pset replaces its base counterpart by name, an untouched one
32
+ * passes through. Same overlay `element-field-reader.ts`'s `typeSetsFor`
33
+ * applies for the Elements chart's own field column (#4946 review). */
34
+ export function typePropertySetsFor(typeBasePsets, typeId, mutationView) {
35
+ if (!mutationView?.hasChanges(typeId))
36
+ return typeBasePsets;
37
+ const overlay = mutationView.getForEntity(typeId);
38
+ const overlayNames = new Set(overlay.map((set) => set.name));
39
+ const visibleBase = typeBasePsets.filter((set) => !mutationView.isPropertySetDeleted(typeId, set.name));
40
+ return [...overlay, ...visibleBase.filter((set) => !overlayNames.has(set.name))];
41
+ }
42
+ /** Overlay sets first, each topped up with any base quantity of the same set
43
+ * name it does not itself name; untouched base sets pass through as-is —
44
+ * same merge `element-field-families.ts`'s `qsetsFor` uses for the same
45
+ * reason: editing one quantity must not hide its siblings or an unrelated
46
+ * quantity set (issue #2487). */
47
+ function overlayFirstQtySets(overlay, base) {
48
+ const byName = new Map(overlay.map((set) => [set.name, set]));
49
+ const merged = overlay.map((set) => {
50
+ const named = new Set(set.quantities.map((q) => q.name));
51
+ const inherited = [];
52
+ for (const baseSet of base) {
53
+ if (baseSet.name !== set.name)
54
+ continue;
55
+ for (const q of baseSet.quantities)
56
+ if (!named.has(q.name)) {
57
+ named.add(q.name);
58
+ inherited.push(q);
59
+ }
60
+ }
61
+ return inherited.length > 0 ? { ...set, quantities: [...set.quantities, ...inherited] } : set;
62
+ });
63
+ return [...merged, ...base.filter((set) => !byName.has(set.name))];
64
+ }
65
+ /** The occurrence's quantity sets, WITH mutations applied when present. A
66
+ * `mutationView` built for a server-hydrated store (no quantity extractor,
67
+ * `!hasQuantityBase()`) answers `getQuantitiesForEntity` from its overlay
68
+ * ALONE, which would otherwise make an edited quantity's siblings — or an
69
+ * untouched quantity set — vanish from a selector's reads; merge the base
70
+ * back in for that case instead of trusting the overlay as the whole set. */
71
+ export function quantitySetsFor(store, expressId, mutationView) {
72
+ if (!mutationView)
73
+ return extractQuantitiesOnDemand(store, expressId);
74
+ const overlay = mutationView.getQuantitiesForEntity(expressId);
75
+ if (mutationView.hasQuantityBase())
76
+ return overlay;
77
+ const base = extractQuantitiesOnDemand(store, expressId).filter((set) => !mutationView.isQuantitySetDeleted(expressId, set.name));
78
+ return overlayFirstQtySets(overlay, base);
79
+ }
80
+ /** The occurrence's root attributes, an edited one overriding its base value
81
+ * by name (order otherwise kept) — same merge `element-field-reader.ts`'s
82
+ * `attrsFor` does. */
83
+ export function attributesFor(store, expressId, mutationView) {
84
+ const created = createdFilterRecord(store, mutationView, expressId);
85
+ if (created) {
86
+ return created.names.flatMap((name, index) => {
87
+ const value = created.attributes[index];
88
+ return (typeof value === 'string' && value !== '$') || typeof value === 'number' || typeof value === 'boolean'
89
+ ? [{ name, value }] : [];
90
+ });
91
+ }
92
+ const base = extractAllEntityAttributes(store, expressId);
93
+ const edits = mutationView?.getAttributeMutationsForEntity(expressId);
94
+ if (!edits || edits.length === 0)
95
+ return base;
96
+ const merged = new Map();
97
+ for (const a of base)
98
+ merged.set(a.name, a);
99
+ for (const e of edits)
100
+ merged.set(e.name, e);
101
+ return [...merged.values()];
102
+ }
103
+ /** An edited value for ONE root attribute (#4946 review), for the two rule
104
+ * kinds that read a dedicated fast-path column instead of `attributesFor`'s
105
+ * full merge: `name` (`ctx.table.getNameOrUndefined`) and `predefinedType`
106
+ * (`resolveEntityPredefinedType`). `undefined` means "no edit" — the caller
107
+ * falls through to its base read, same as an unedited `attributesFor` row. */
108
+ export function mutatedAttributeValue(mutationView, expressId, attrName) {
109
+ return mutationView?.getAttributeMutationsForEntity(expressId).find((e) => e.name === attrName)?.value;
110
+ }
111
+ //# sourceMappingURL=filter-evaluate-mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-evaluate-mutations.js","sourceRoot":"","sources":["../../src/filter/filter-evaluate-mutations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Event-loop plumbing for the chunked federated evaluator (`filter-evaluate.ts`). */
2
+ export declare function throwAbort(signal: AbortSignal): never;
3
+ /** Yield control to the event loop. Mirrors `tier1-index.ts` so we
4
+ * don't pin the Node test runner — `scheduler.yield` (browsers /
5
+ * Node 22+) and `setImmediate` (Node fallback) are preferred over
6
+ * the MessageChannel trick because the latter requires explicit
7
+ * port closure to release the loop reference. */
8
+ export declare function yieldToEventLoop(): Promise<void>;
9
+ //# sourceMappingURL=filter-evaluate-yield.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-evaluate-yield.d.ts","sourceRoot":"","sources":["../../src/filter/filter-evaluate-yield.ts"],"names":[],"mappings":"AAIA,sFAAsF;AAEtF,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAOrD;AAED;;;;kDAIkD;AAClD,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBhD"}
@@ -0,0 +1,32 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** Event-loop plumbing for the chunked federated evaluator (`filter-evaluate.ts`). */
5
+ export function throwAbort(signal) {
6
+ // Match the shape DOM throws on AbortController.signal.aborted reads —
7
+ // callers can `instanceof DOMException && err.name === 'AbortError'`.
8
+ throw new DOMException(signal.reason instanceof Error ? signal.reason.message : 'evaluateFilterRules aborted', 'AbortError');
9
+ }
10
+ /** Yield control to the event loop. Mirrors `tier1-index.ts` so we
11
+ * don't pin the Node test runner — `scheduler.yield` (browsers /
12
+ * Node 22+) and `setImmediate` (Node fallback) are preferred over
13
+ * the MessageChannel trick because the latter requires explicit
14
+ * port closure to release the loop reference. */
15
+ export function yieldToEventLoop() {
16
+ const maybeScheduler = globalThis.scheduler;
17
+ if (typeof maybeScheduler?.yield === 'function')
18
+ return maybeScheduler.yield();
19
+ if (typeof setImmediate === 'function') {
20
+ return new Promise((resolve) => { setImmediate(() => resolve()); });
21
+ }
22
+ return new Promise((resolve) => {
23
+ const channel = new MessageChannel();
24
+ channel.port1.onmessage = () => {
25
+ channel.port1.close();
26
+ channel.port2.close();
27
+ resolve();
28
+ };
29
+ channel.port2.postMessage(null);
30
+ });
31
+ }
32
+ //# sourceMappingURL=filter-evaluate-yield.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-evaluate-yield.js","sourceRoot":"","sources":["../../src/filter/filter-evaluate-yield.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,sFAAsF;AAEtF,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,uEAAuE;IACvE,sEAAsE;IACtE,MAAM,IAAI,YAAY,CACpB,MAAM,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,EACtF,YAAY,CACb,CAAC;AACJ,CAAC;AAED;;;;kDAIkD;AAClD,MAAM,UAAU,gBAAgB;IAC9B,MAAM,cAAc,GAAI,UAEtB,CAAC,SAAS,CAAC;IACb,IAAI,OAAO,cAAc,EAAE,KAAK,KAAK,UAAU;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/E,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE,CAAC;QACvC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Path-B runtime evaluator.
3
+ *
4
+ * Applies a list of `FilterRule`s to one or more `IfcDataStore`s without
5
+ * touching DuckDB. Three optimisations make this safe on huge (4M-entity)
6
+ * models without a Worker:
7
+ *
8
+ * 1. **Index prefilter (AND + op:in only).** When the rule list contains
9
+ * any `ifcType` or `storey` `op:'in'` rule under an AND combinator,
10
+ * the iteration source is derived from `entityIndex.byType` /
11
+ * `spatialHierarchy.byStorey` — typically 100× narrowing. Per-entity
12
+ * rule evaluation still re-checks every rule for correctness, so
13
+ * picking one prefilter (the smallest bucket) is enough; we don't
14
+ * need to intersect. `notIn` and `OR` skip the prefilter and fall
15
+ * back to the full column scan.
16
+ *
17
+ * 2. **Cheap-first per-entity ordering.** Rules are sorted by cost at
18
+ * evaluation time so column-only checks (`ifcType`, `name`, `storey`,
19
+ * `predefinedType`) run before `property` / `quantity` rules that
20
+ * trigger on-demand source-buffer parses. Combined with AND/OR
21
+ * short-circuit, this avoids the AGENTS.md §2 "never call
22
+ * extractPropertiesOnDemand in a large loop" trap — a single
23
+ * ifcType rule excluding 99% of entities skips 99% of the parses.
24
+ *
25
+ * 3. **Async chunked yielding (federated entry).** The federated entry
26
+ * is async and yields to the event loop every `chunkSize` rows
27
+ * (default 20_000, same as `buildTier1Index`). `AbortSignal` is
28
+ * honoured at chunk boundaries; an `onProgress(scanned, total)`
29
+ * callback fires once per chunk. The synchronous single-model
30
+ * entry remains for tests and small candidate sets.
31
+ */
32
+ import { type IfcDataStore } from '@ifc-lite/parser';
33
+ import type { MutablePropertyView } from '@ifc-lite/mutations';
34
+ import { type Combinator, type FilterRule } from './filter-rules.js';
35
+ import { selectIterationSource, orderRulesByCost } from './filter-iteration-source.js';
36
+ import { flattenPsets, flattenQtys, stringifyValue, matchPropertyRule, matchQuantityRule, matchAttributeRule, materialNamesOf, matchClassificationRule, elevationOf } from './filter-match.js';
37
+ /** A single matched element. Mirrors the Rust `FilteredElement` shape. */
38
+ export interface FilteredElement {
39
+ modelId: string;
40
+ expressId: number;
41
+ ifcType: string;
42
+ name: string;
43
+ globalId: string;
44
+ }
45
+ export interface EvaluateOptions {
46
+ /**
47
+ * Restrict evaluation to these expressIds (e.g. the result list from
48
+ * Tier-1). Omit to scan every populated entity in the store, with
49
+ * index prefilters applied where possible.
50
+ */
51
+ candidateExpressIds?: Iterable<number>;
52
+ /** Cap. Default 5_000 — enough for downstream batch ops, cheap to bump. */
53
+ limit?: number;
54
+ /** Optional storey-name resolver. Falls back to spatial-hierarchy lookup. */
55
+ storeyNameOf?: (expressId: number) => string;
56
+ /** Optional predefined-type resolver. Falls back to "" when omitted. */
57
+ predefinedTypeOf?: (expressId: number) => string;
58
+ /** Stable identity used by persisted model rules; defaults to `modelId`. */
59
+ modelFilterIdentity?: string;
60
+ /** This model's tag ids (`modelTag` rules, #4215); absent = untagged. */
61
+ modelTagIds?: ReadonlySet<string>;
62
+ /** Every tag id that exists. A `modelTag` rule naming any other id is
63
+ * UNRESOLVED and matches nothing — absent means "no tags exist", so every
64
+ * rule naming a tag is unresolved, never silently broad. */
65
+ definedModelTagIds?: ReadonlySet<string>;
66
+ }
67
+ /**
68
+ * Evaluate `rules` against one model synchronously. Suitable for tests
69
+ * and small candidate sets where the chunked async path's overhead
70
+ * isn't justified. For real UI flows (huge models, cancellable runs),
71
+ * use `evaluateFilterRulesFederated` (async).
72
+ */
73
+ export declare function evaluateFilterRules(modelId: string, store: IfcDataStore, rules: readonly FilterRule[], combinator: Combinator, options?: EvaluateOptions): FilteredElement[];
74
+ export interface FederatedEvaluateOptions extends Omit<EvaluateOptions, 'candidateExpressIds'> {
75
+ /**
76
+ * Optional per-model candidate set. When supplied for a model, only
77
+ * those expressIds are evaluated (the typical use is "narrow with
78
+ * Tier-1 first, then verify structured rules"). Models absent from
79
+ * the map fall back to a full scan with index prefilters applied.
80
+ * Pass an empty iterable to skip a model entirely.
81
+ */
82
+ candidateExpressIdsByModel?: ReadonlyMap<string, Iterable<number>>;
83
+ /** Rows per yield boundary. Default 20_000. */
84
+ chunkSize?: number;
85
+ /** Aborts the run between chunks. Throws DOMException("…", "AbortError"). */
86
+ signal?: AbortSignal;
87
+ /** Progress callback fired after each chunk: (scanned, total). When
88
+ * `total` is unknown (Tier-1 candidate iterables without `.size`),
89
+ * it's reported as -1. */
90
+ onProgress?: (scanned: number, total: number) => void;
91
+ }
92
+ /**
93
+ * Evaluate `rules` across multiple federated models, producing a single
94
+ * sorted result list. Async chunked + cancellable + progress-reporting.
95
+ */
96
+ /** One federated model as the evaluator sees it. `tagIds` is the model's tag
97
+ * set at call time — a SNAPSHOT: re-tagging while a run is in flight does not
98
+ * change what the run matches (the clash resolver relies on this, #4215). */
99
+ export interface EvaluatorModel {
100
+ id: string;
101
+ filterIdentity?: string;
102
+ tagIds?: ReadonlySet<string>;
103
+ store: IfcDataStore | null;
104
+ mutationView?: MutablePropertyView;
105
+ }
106
+ export declare function evaluateFilterRulesFederated(models: ReadonlyArray<EvaluatorModel>, rules: readonly FilterRule[], combinator: Combinator, options?: FederatedEvaluateOptions): Promise<FilteredElement[]>;
107
+ export declare const __internal: {
108
+ flattenPsets: typeof flattenPsets;
109
+ flattenQtys: typeof flattenQtys;
110
+ stringifyValue: typeof stringifyValue;
111
+ matchPropertyRule: typeof matchPropertyRule;
112
+ matchQuantityRule: typeof matchQuantityRule;
113
+ matchAttributeRule: typeof matchAttributeRule;
114
+ materialNamesOf: typeof materialNamesOf;
115
+ matchClassificationRule: typeof matchClassificationRule;
116
+ elevationOf: typeof elevationOf;
117
+ orderRulesByCost: typeof orderRulesByCost;
118
+ selectIterationSource: typeof selectIterationSource;
119
+ };
120
+ //# sourceMappingURL=filter-evaluate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-evaluate.d.ts","sourceRoot":"","sources":["../../src/filter/filter-evaluate.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAML,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAC;AAa3B,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAWvF,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAGlB,eAAe,EACf,uBAAuB,EACvB,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAM3B,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yEAAyE;IACzE,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC;;iEAE6D;IAC7D,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAOD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,eAAoB,GAC5B,eAAe,EAAE,CAsCnB;AAID,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CAAC,eAAe,EAAE,qBAAqB,CAAC;IAC5F;;;;;;OAMG;IACH,0BAA0B,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;+BAE2B;IAC3B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD;AAED;;;GAGG;AACH;;8EAE8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CAChE;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,EACrC,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,eAAe,EAAE,CAAC,CA8G5B;AAqOD,eAAO,MAAM,UAAU;;;;;;;;;;;;CAYtB,CAAC"}