@cruba/crubal 0.1.0 → 0.3.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 (89) hide show
  1. package/README.md +30 -2
  2. package/dist/bin/crubal.js +70 -4
  3. package/dist/bin/crubal.js.map +1 -1
  4. package/dist/src/access.d.ts +126 -0
  5. package/dist/src/access.js +517 -0
  6. package/dist/src/access.js.map +1 -0
  7. package/dist/src/address.d.ts +29 -0
  8. package/dist/src/address.js +59 -0
  9. package/dist/src/address.js.map +1 -0
  10. package/dist/src/arrival.d.ts +55 -0
  11. package/dist/src/arrival.js +124 -0
  12. package/dist/src/arrival.js.map +1 -0
  13. package/dist/src/bundle.d.ts +66 -0
  14. package/dist/src/bundle.js +753 -0
  15. package/dist/src/bundle.js.map +1 -0
  16. package/dist/src/conditions.d.ts +7 -1
  17. package/dist/src/conditions.js +52 -11
  18. package/dist/src/conditions.js.map +1 -1
  19. package/dist/src/corpus.js +568 -34
  20. package/dist/src/corpus.js.map +1 -1
  21. package/dist/src/defs.d.ts +37 -2
  22. package/dist/src/defs.js +95 -14
  23. package/dist/src/defs.js.map +1 -1
  24. package/dist/src/dictionary.d.ts +15 -0
  25. package/dist/src/dictionary.js +72 -13
  26. package/dist/src/dictionary.js.map +1 -1
  27. package/dist/src/exchange.d.ts +204 -11
  28. package/dist/src/exchange.js +762 -45
  29. package/dist/src/exchange.js.map +1 -1
  30. package/dist/src/forms.d.ts +16 -0
  31. package/dist/src/forms.js +169 -0
  32. package/dist/src/forms.js.map +1 -0
  33. package/dist/src/index.d.ts +19 -6
  34. package/dist/src/index.js +18 -5
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/lifecycle.d.ts +84 -0
  37. package/dist/src/lifecycle.js +415 -0
  38. package/dist/src/lifecycle.js.map +1 -0
  39. package/dist/src/log.d.ts +78 -0
  40. package/dist/src/log.js +506 -0
  41. package/dist/src/log.js.map +1 -0
  42. package/dist/src/migrate.d.ts +24 -1
  43. package/dist/src/migrate.js +104 -9
  44. package/dist/src/migrate.js.map +1 -1
  45. package/dist/src/model.d.ts +33 -1
  46. package/dist/src/model.js +158 -2
  47. package/dist/src/model.js.map +1 -1
  48. package/dist/src/packages.d.ts +44 -0
  49. package/dist/src/packages.js +137 -3
  50. package/dist/src/packages.js.map +1 -1
  51. package/dist/src/print-text.js +22 -0
  52. package/dist/src/print-text.js.map +1 -1
  53. package/dist/src/publish.d.ts +27 -0
  54. package/dist/src/publish.js +275 -0
  55. package/dist/src/publish.js.map +1 -0
  56. package/dist/src/read-text.d.ts +2 -0
  57. package/dist/src/read-text.js +72 -4
  58. package/dist/src/read-text.js.map +1 -1
  59. package/dist/src/records.d.ts +32 -0
  60. package/dist/src/records.js +104 -0
  61. package/dist/src/records.js.map +1 -0
  62. package/dist/src/review.d.ts +22 -0
  63. package/dist/src/review.js +198 -0
  64. package/dist/src/review.js.map +1 -0
  65. package/dist/src/rules.d.ts +38 -3
  66. package/dist/src/rules.js +184 -30
  67. package/dist/src/rules.js.map +1 -1
  68. package/dist/src/schedule.d.ts +24 -0
  69. package/dist/src/schedule.js +126 -0
  70. package/dist/src/schedule.js.map +1 -0
  71. package/dist/src/std-packages.d.ts +9 -0
  72. package/dist/src/std-packages.js +268 -0
  73. package/dist/src/std-packages.js.map +1 -0
  74. package/dist/src/store.d.ts +38 -7
  75. package/dist/src/store.js +166 -24
  76. package/dist/src/store.js.map +1 -1
  77. package/dist/src/tree.d.ts +3 -0
  78. package/dist/src/tree.js +36 -0
  79. package/dist/src/tree.js.map +1 -1
  80. package/dist/src/units-table.d.ts +1 -0
  81. package/dist/src/units-table.js +200 -0
  82. package/dist/src/units-table.js.map +1 -0
  83. package/dist/src/units.d.ts +42 -4
  84. package/dist/src/units.js +91 -30
  85. package/dist/src/units.js.map +1 -1
  86. package/dist/src/views.d.ts +116 -6
  87. package/dist/src/views.js +484 -74
  88. package/dist/src/views.js.map +1 -1
  89. package/package.json +5 -3
@@ -0,0 +1,200 @@
1
+ // units-table.ts: the standard units table, crubal.com/units, as published in std/units/units.crubal. Generated by
2
+ // `npm run embed` in packages/crubal; a test refuses a copy that has drifted from the file.
3
+ export const STANDARD_UNITS = `// The units table's records (11.9). The base unit of each dimension has factor 1 and states the rounding a
4
+ // conversion keeps when the facet states none.
5
+ crubal: 2
6
+ package: crubal.com/units /2026-10-15
7
+ owner: crubal.com
8
+
9
+ measure: s
10
+ dimension: time
11
+ factor: 1
12
+ rounding: 3
13
+ spellings: sec, secs, second, seconds
14
+ uncefact: SEC
15
+ measure: min
16
+ dimension: time
17
+ factor: 60
18
+ spellings: MIN., mins, minute, minutes
19
+ uncefact: MIN
20
+ measure: h
21
+ dimension: time
22
+ factor: 3600
23
+ spellings: hr, hrs, hour, hours
24
+ uncefact: HUR
25
+ measure: d
26
+ dimension: time
27
+ factor: 86400
28
+ spellings: day, days
29
+ uncefact: DAY
30
+
31
+ measure: m
32
+ dimension: length
33
+ factor: 1
34
+ rounding: 4
35
+ spellings: meter, meters, metre, metres
36
+ uncefact: MTR
37
+ measure: mm
38
+ dimension: length
39
+ factor: 0.001
40
+ uncefact: MMT
41
+ measure: cm
42
+ dimension: length
43
+ factor: 0.01
44
+ uncefact: CMT
45
+ measure: km
46
+ dimension: length
47
+ factor: 1000
48
+ uncefact: KMT
49
+ measure: in
50
+ dimension: length
51
+ factor: 0.0254
52
+ spellings: inch, inches
53
+ uncefact: INH
54
+ measure: ft
55
+ dimension: length
56
+ factor: 0.3048
57
+ spellings: foot, feet
58
+ uncefact: FOT
59
+ measure: mi
60
+ dimension: length
61
+ factor: 1609.344
62
+ spellings: mile, miles
63
+ uncefact: SMI
64
+
65
+ measure: kg
66
+ dimension: mass
67
+ factor: 1
68
+ rounding: 4
69
+ spellings: kilogram, kilograms
70
+ uncefact: KGM
71
+ measure: g
72
+ dimension: mass
73
+ factor: 0.001
74
+ spellings: gram, grams
75
+ uncefact: GRM
76
+ measure: oz
77
+ dimension: mass
78
+ factor: 0.028349523125
79
+ spellings: ounce, ounces
80
+ uncefact: ONZ
81
+ measure: lb
82
+ dimension: mass
83
+ factor: 0.45359237
84
+ spellings: lbs, pound, pounds
85
+ uncefact: LBR
86
+
87
+ measure: L
88
+ dimension: volume
89
+ factor: 1
90
+ rounding: 3
91
+ spellings: l, liter, liters, litre, litres
92
+ uncefact: LTR
93
+ measure: mL
94
+ dimension: volume
95
+ factor: 0.001
96
+ spellings: ml, milliliter, milliliters, millilitre, millilitres
97
+ uncefact: MLT
98
+ measure: floz
99
+ dimension: volume
100
+ factor: 0.0295735295625
101
+ spellings: fl oz, fl. oz., fluid ounce, fluid ounces
102
+ uncefact: OZA
103
+ measure: gal
104
+ dimension: volume
105
+ factor: 3.785411784
106
+ spellings: gallon, gallons
107
+ uncefact: GLL
108
+
109
+ measure: m2
110
+ dimension: area
111
+ factor: 1
112
+ rounding: 4
113
+ spellings: m², sqm, square meter, square meters
114
+ uncefact: MTK
115
+ measure: ft2
116
+ dimension: area
117
+ factor: 0.09290304
118
+ spellings: ft², sqft, square foot, square feet
119
+ uncefact: FTK
120
+
121
+ measure: K
122
+ dimension: temperature
123
+ factor: 1
124
+ rounding: 2
125
+ spellings: kelvin
126
+ uncefact: KEL
127
+ measure: °C
128
+ dimension: temperature
129
+ factor: 1
130
+ offset: 273.15
131
+ spellings: C, degC, celsius
132
+ uncefact: CEL
133
+ measure: °F
134
+ dimension: temperature
135
+ factor: 0.5555555555555556
136
+ offset: 255.37222222222223
137
+ spellings: F, degF, fahrenheit
138
+ uncefact: FAH
139
+
140
+ measure: B
141
+ dimension: data
142
+ factor: 1
143
+ rounding: 0
144
+ spellings: byte, bytes
145
+ uncefact: AD
146
+ measure: KB
147
+ dimension: data
148
+ factor: 1000
149
+ uncefact: 2P
150
+ measure: MB
151
+ dimension: data
152
+ factor: 1000000
153
+ uncefact: 4L
154
+ measure: GB
155
+ dimension: data
156
+ factor: 1000000000
157
+ uncefact: E34
158
+ measure: TB
159
+ dimension: data
160
+ factor: 1000000000000
161
+ uncefact: E35
162
+
163
+ measure: each
164
+ dimension: count
165
+ factor: 1
166
+ rounding: 0
167
+ spellings: ea, pc, pcs, piece, pieces
168
+ uncefact: EA
169
+ measure: dozen
170
+ dimension: count
171
+ factor: 12
172
+ spellings: dz, doz
173
+ uncefact: DZN
174
+
175
+ currency: USD
176
+ name: US dollar
177
+ places: 2
178
+ currency: EUR
179
+ name: Euro
180
+ places: 2
181
+ currency: GBP
182
+ name: Pound sterling
183
+ places: 2
184
+ currency: CAD
185
+ name: Canadian dollar
186
+ places: 2
187
+ currency: AUD
188
+ name: Australian dollar
189
+ places: 2
190
+ currency: MXN
191
+ name: Mexican peso
192
+ places: 2
193
+ currency: JPY
194
+ name: Yen
195
+ places: 0
196
+ currency: BHD
197
+ name: Bahraini dinar
198
+ places: 3
199
+ `;
200
+ //# sourceMappingURL=units-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"units-table.js","sourceRoot":"","sources":["../../src/units-table.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,4FAA4F;AAE5F,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoM7B,CAAC"}
@@ -1,4 +1,42 @@
1
- /** The real unit a spelling names, or null. */
2
- export declare function unitOf(spelling: string): string | null;
3
- /** Convert an amount between units of one dimension, rounded to `places` (default: up to 6). */
4
- export declare function convert(amount: string, from: string, to: string, places?: number): string | null;
1
+ export type Unit = {
2
+ unit: string;
3
+ dimension: string;
4
+ factor: number;
5
+ offset: number;
6
+ rounding?: number;
7
+ spellings: string[];
8
+ uncefact?: string;
9
+ extension?: boolean;
10
+ };
11
+ export type Currency = {
12
+ code: string;
13
+ name: string;
14
+ places: number;
15
+ };
16
+ export type UnitsTable = {
17
+ units: Map<string, Unit>;
18
+ currencies: Map<string, Currency>;
19
+ version: string;
20
+ };
21
+ /** Read a units table's records (measure and currency) from the text form. */
22
+ export declare function readUnits(text: string, into?: UnitsTable, extension?: boolean): UnitsTable;
23
+ /** The table in force: the standard table at its version, plus any extension. */
24
+ export declare function unitsTable(): UnitsTable;
25
+ /** Add an owner's units extension (11.9): its own units under its prefix, and spellings for standard ones. */
26
+ export declare function extendUnits(text: string): UnitsTable;
27
+ /** Back to the standard table alone. */
28
+ export declare function resetUnits(): void;
29
+ /** The real unit a spelling names, or null: the unit itself, or one of its spellings, folded. */
30
+ export declare function unitOf(spelling: string, table?: UnitsTable): string | null;
31
+ /** Is this a unit the table knows, `currency`, or an ISO 4217 code (1.4.4)? */
32
+ export declare function knownUnit(u: string, table?: UnitsTable): boolean;
33
+ export declare function dimensionOf(unit: string, table?: UnitsTable): string | null;
34
+ /** A currency's minor-unit places (ISO 4217), for a border that asks for them; 2 when unknown. */
35
+ export declare function currencyPlaces(code: string, table?: UnitsTable): number;
36
+ /**
37
+ * Convert an amount between units of one dimension: through the base by factor and offset, rounded to
38
+ * `places`, else the dimension's rounding, else 6 places with trailing zeros dropped.
39
+ */
40
+ export declare function convert(amount: string, from: string, to: string, places?: number, table?: UnitsTable): string | null;
41
+ /** The standard table plus one owner's extension, as a table of its own (11.9): per dictionary, never global. */
42
+ export declare function unitsTableWith(extension?: string): UnitsTable;
package/dist/src/units.js CHANGED
@@ -1,37 +1,98 @@
1
- // units.ts: a starter units table, standing in for the standard units package (spec chapter 11.1,
2
- // `crubal.com/units`) until it is published. Each unit has a dimension and a factor to the dimension's base.
3
- const TABLE = {
4
- s: { dimension: "time", factor: 1, spellings: ["sec", "secs", "second", "seconds"] },
5
- min: { dimension: "time", factor: 60, spellings: ["MIN.", "mins", "minute", "minutes"] },
6
- h: { dimension: "time", factor: 3600, spellings: ["hr", "hrs", "hour", "hours"] },
7
- mm: { dimension: "length", factor: 0.001, spellings: [] },
8
- cm: { dimension: "length", factor: 0.01, spellings: [] },
9
- m: { dimension: "length", factor: 1, spellings: [] },
10
- in: { dimension: "length", factor: 0.0254, spellings: ["inch", "inches", '"'] },
11
- ft: { dimension: "length", factor: 0.3048, spellings: ["foot", "feet"] },
12
- g: { dimension: "mass", factor: 0.001, spellings: [] },
13
- kg: { dimension: "mass", factor: 1, spellings: [] },
14
- oz: { dimension: "mass", factor: 0.028349523125, spellings: [] },
15
- lb: { dimension: "mass", factor: 0.45359237, spellings: ["lbs", "pound", "pounds"] },
16
- };
17
- /** The real unit a spelling names, or null. */
18
- export function unitOf(spelling) {
19
- if (TABLE[spelling])
1
+ // units.ts: the units table (spec 1.4.3, 11.9), read from the standard package's reference records
2
+ // (crubal.com/units, embedded as units-table.ts and checked against std/units/units.crubal) plus an owner's
3
+ // extension. Spellings fold to a unit; amounts convert within a dimension by factor and offset, rounded to
4
+ // the facet's places or the dimension's rounding. A spelling nobody knows is a unit question for review,
5
+ // never a unit minted on sight.
6
+ import { readTree } from "./tree.js";
7
+ import { STANDARD_UNITS } from "./units-table.js";
8
+ const foldSpelling = (s) => s.normalize("NFC").toLowerCase().replace(/\s+/g, " ").trim();
9
+ /** Read a units table's records (measure and currency) from the text form. */
10
+ export function readUnits(text, into, extension = false) {
11
+ const table = into ?? { units: new Map(), currencies: new Map(), version: "" };
12
+ for (const n of readTree(text)) {
13
+ if (n.kind !== "pair" || !n.key)
14
+ continue;
15
+ const get = (k) => n.children.find((c) => c.key === k)?.value.trim();
16
+ if (n.key === "package")
17
+ table.version = n.value.split(" /")[1]?.trim() ?? table.version;
18
+ if (n.key === "measure") {
19
+ const name = n.value.trim();
20
+ const have = table.units.get(name);
21
+ const spellings = (get("spellings") ?? "").split(",").map((s) => s.trim()).filter(Boolean);
22
+ // An extension may add spellings to a standard unit; it never changes its factor or dimension (11.9).
23
+ if (have && extension) {
24
+ have.spellings = [...have.spellings, ...spellings.filter((s) => !have.spellings.includes(s))];
25
+ continue;
26
+ }
27
+ const u = { unit: name, dimension: get("dimension") ?? "", factor: Number(get("factor") ?? 1), offset: Number(get("offset") ?? 0), spellings, ...(extension ? { extension: true } : {}) };
28
+ const r = get("rounding");
29
+ if (r !== undefined)
30
+ u.rounding = Number(r);
31
+ const code = get("uncefact");
32
+ if (code)
33
+ u.uncefact = code;
34
+ table.units.set(name, u);
35
+ }
36
+ if (n.key === "currency")
37
+ table.currencies.set(n.value.trim(), { code: n.value.trim(), name: get("name") ?? "", places: Number(get("places") ?? 2) });
38
+ }
39
+ return table;
40
+ }
41
+ let current = readUnits(STANDARD_UNITS);
42
+ /** The table in force: the standard table at its version, plus any extension. */
43
+ export function unitsTable() {
44
+ return current;
45
+ }
46
+ /** Add an owner's units extension (11.9): its own units under its prefix, and spellings for standard ones. */
47
+ export function extendUnits(text) {
48
+ current = readUnits(text, current, true);
49
+ return current;
50
+ }
51
+ /** Back to the standard table alone. */
52
+ export function resetUnits() {
53
+ current = readUnits(STANDARD_UNITS);
54
+ }
55
+ /** The real unit a spelling names, or null: the unit itself, or one of its spellings, folded. */
56
+ export function unitOf(spelling, table = current) {
57
+ if (table.units.has(spelling))
20
58
  return spelling;
21
- const lower = spelling.toLowerCase();
22
- for (const [u, def] of Object.entries(TABLE))
23
- if (def.spellings.some((s) => s.toLowerCase() === lower))
24
- return u;
59
+ const k = foldSpelling(spelling);
60
+ for (const u of table.units.values())
61
+ if (u.unit.toLowerCase() === k || u.spellings.some((s) => foldSpelling(s) === k))
62
+ return u.unit;
25
63
  return null;
26
64
  }
27
- /** Convert an amount between units of one dimension, rounded to `places` (default: up to 6). */
28
- export function convert(amount, from, to, places) {
29
- const a = TABLE[from];
30
- const b = TABLE[to];
65
+ /** Is this a unit the table knows, `currency`, or an ISO 4217 code (1.4.4)? */
66
+ export function knownUnit(u, table = current) {
67
+ return u === "currency" || /^[A-Z]{3}$/.test(u) || table.units.has(u);
68
+ }
69
+ export function dimensionOf(unit, table = current) {
70
+ return table.units.get(unit)?.dimension ?? null;
71
+ }
72
+ /** A currency's minor-unit places (ISO 4217), for a border that asks for them; 2 when unknown. */
73
+ export function currencyPlaces(code, table = current) {
74
+ return table.currencies.get(code)?.places ?? 2;
75
+ }
76
+ /**
77
+ * Convert an amount between units of one dimension: through the base by factor and offset, rounded to
78
+ * `places`, else the dimension's rounding, else 6 places with trailing zeros dropped.
79
+ */
80
+ export function convert(amount, from, to, places, table = current) {
81
+ const a = table.units.get(from);
82
+ const b = table.units.get(to);
31
83
  if (!a || !b || a.dimension !== b.dimension)
32
84
  return null;
33
- const v = (Number(amount) * a.factor) / b.factor;
34
- const fixed = v.toFixed(places ?? 6);
35
- return places === undefined ? String(Number(fixed)) : fixed;
85
+ const base = Number(amount) * a.factor + a.offset;
86
+ const v = (base - b.offset) / b.factor;
87
+ // The facet's places are kept exactly; the dimension's rounding is a most, trailing zeros dropped.
88
+ if (places !== undefined)
89
+ return v.toFixed(places);
90
+ const dimRounding = [...table.units.values()].find((u) => u.dimension === a.dimension && u.factor === 1 && u.offset === 0)?.rounding;
91
+ return String(Number(v.toFixed(dimRounding ?? 6)));
92
+ }
93
+ /** The standard table plus one owner's extension, as a table of its own (11.9): per dictionary, never global. */
94
+ export function unitsTableWith(extension) {
95
+ const table = readUnits(STANDARD_UNITS);
96
+ return extension ? readUnits(extension, table, true) : table;
36
97
  }
37
98
  //# sourceMappingURL=units.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/units.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/units.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
+ import type { Access } from "./access.ts";
1
2
  import type { Dictionary } from "./defs.ts";
3
+ export { facetOf, leafOf } from "./address.ts";
2
4
  import type { Json, JsonObject, Record } from "./model.ts";
5
+ import { type RecordSet } from "./records.ts";
3
6
  export declare const AUDIENCES: readonly ["public", "member", "staff", "owner"];
4
7
  export type Slot = {
5
8
  from: string;
@@ -46,6 +49,10 @@ export type View = {
46
49
  indexLine: number;
47
50
  show: string;
48
51
  fresh: string;
52
+ /** `administered`, `controlled`, `owned`, `relation <name>` or `none` (12.2); absent takes the default. */
53
+ partition?: string;
54
+ /** The dated version; a new version starts the view's stream over (12.6). */
55
+ version?: string;
49
56
  };
50
57
  export type RoleDef = {
51
58
  name: string;
@@ -54,15 +61,28 @@ export type RoleDef = {
54
61
  seeLine: number;
55
62
  line: number;
56
63
  };
64
+ /** A show rule with a `for`: it decides for the records its class, kind or level covers (12.4). */
65
+ export type ShownFor = {
66
+ for: string;
67
+ audience: string;
68
+ };
57
69
  export type ViewSet = {
58
70
  shapes: Map<string, Shape>;
59
71
  filters: Map<string, Filter>;
60
72
  views: Map<string, View>;
61
73
  roles: Map<string, RoleDef>;
62
74
  shown: Map<string, string>;
75
+ shownFor: Map<string, ShownFor[]>;
63
76
  };
64
77
  /** Read shapes, filters, views (with a body), roles and `shown to` rules. */
65
78
  export declare function readViews(source: string): ViewSet;
79
+ /**
80
+ * The lowest audience that may see a facet (12.4): a show rule whose `for` covers the record decides for it,
81
+ * a class over a kind or level, else the rule for everywhere; no rule, the public.
82
+ */
83
+ export declare function shownAudience(set: Pick<ViewSet, "shown" | "shownFor">, facet: string, record?: Pick<Record, "kind" | "level" | "wears">, dict?: Pick<Dictionary, "kinds">): string | undefined;
84
+ /** Can an audience see a facet, of this record when one is given? */
85
+ export declare function visibleTo(set: Pick<ViewSet, "shown" | "shownFor">, facet: string, audience: string, record?: Pick<Record, "kind" | "level" | "wears">, dict?: Pick<Dictionary, "kinds">): boolean;
66
86
  export declare function checkViews(set: ViewSet, dict: Dictionary): void;
67
87
  export type ProjectOptions = {
68
88
  audience?: string;
@@ -72,39 +92,129 @@ export type ProjectOptions = {
72
92
  [filter: string]: string[];
73
93
  };
74
94
  page?: number;
95
+ /** Access (chapter 14) for partitioned views: the index serves a caller only the rows their edges match. */
96
+ access?: Access;
97
+ /** Only these records: a projector rebuilding the rows a write made stale (12.6) asks for them alone. */
98
+ only?: string[];
99
+ /**
100
+ * Every row in one pass, no page and no counts: a projector publishing the view (12.6) wants the rows,
101
+ * and a page at a time would select and count the whole view once per page (ME: 197 pages of 9,437 units).
102
+ */
103
+ all?: boolean;
104
+ };
105
+ export type Counts = {
106
+ [filter: string]: {
107
+ [bucket: string]: number;
108
+ };
109
+ };
110
+ /** Dependent counts (12.3): filter → bucket → dependent facet → value → count. */
111
+ export type Nested = {
112
+ [filter: string]: {
113
+ [bucket: string]: {
114
+ [dependent: string]: {
115
+ [value: string]: number;
116
+ };
117
+ };
118
+ };
75
119
  };
76
120
  export type Projection = {
77
121
  rows: JsonObject[];
78
122
  records: string[];
79
- counts: {
80
- [filter: string]: {
81
- [bucket: string]: number;
82
- };
83
- };
123
+ counts: Counts;
124
+ nested?: Nested;
84
125
  pages: number;
85
126
  indexable: boolean;
86
127
  };
128
+ /** One entry of a view's projection stream (12.6, 12.7). */
129
+ export type StreamEntry = {
130
+ projection: string;
131
+ audience: string;
132
+ seq: number;
133
+ record: string;
134
+ row?: JsonObject;
135
+ buckets?: JsonObject;
136
+ sort?: string[];
137
+ pin?: number;
138
+ removed?: true;
139
+ reset?: true;
140
+ };
141
+ /** The shapes the core defines (12.1, 12.5): the portable one, and structured data for the public. */
142
+ export declare const CORE_SHAPES: string[];
143
+ /** A view's partition: what it declares, else `controlled` above member and `none` otherwise (12.2). */
144
+ export declare function partitionOf(v: View): string;
87
145
  export declare class Views {
88
146
  readonly dict: Dictionary;
89
147
  readonly set: ViewSet;
90
148
  private records;
91
149
  private engine;
92
- constructor(dict: Dictionary, set: ViewSet);
150
+ /** Over a record set of the caller's (a store's working set), or an empty memory set to `put` into. */
151
+ constructor(dict: Dictionary, set: ViewSet, records?: RecordSet);
93
152
  put(r: Record): void;
94
153
  private effective;
154
+ /** The classes a record wears, those of the records above it included (5.5). */
155
+ private wearsOf;
95
156
  private below;
157
+ /**
158
+ * The records a link facet points at: shared parts, read through (1.6). A link into a vocabulary (`wd`,
159
+ * `gpc`) or to a url points at no record here and reads nothing.
160
+ */
161
+ private linked;
162
+ /** The rows of a compound on a record, as objects. */
163
+ private rowsOf;
96
164
  /** The values an address reads, as a list: own values, or a lower level's (`unit::price`). */
97
165
  private valuesAt;
98
166
  /** Is a value fit for this audience's eyes? New, unknown and held values never reach the public. */
99
167
  private fit;
100
168
  private canSee;
101
169
  private slot;
170
+ /**
171
+ * What a condition reads of a record (6.3): the envelope under `crubal:`, and bare `id` and `status`
172
+ * too unless a facet of that name holds a value, which then wins.
173
+ */
174
+ private conditionValues;
175
+ /** The values of the view's order keys as text, and the pin position: what an index orders rows by (12.7). */
176
+ sortOf(v: View, r: Record): {
177
+ sort: string[];
178
+ pin?: number;
179
+ };
180
+ /** The buckets a record falls into, per filter of the view (12.6): what an index counts from. */
181
+ bucketsFor(v: View, r: Record): JsonObject;
182
+ /** Dependent counts (12.3) over records already narrowed by the other filters. */
183
+ nestedCounts(v: View, pool: (f: string) => Record[]): Nested;
184
+ /** Does a view select this record (its own tests, before curation and the shape's required slots)? */
185
+ private selects;
186
+ /** The records a list holds, in its order (12.2): the links in its `crubal:items`. */
187
+ private listed;
102
188
  private inBucket;
103
189
  private bucketsOf;
104
190
  /** The records a view selects, curated and ordered, before filters and paging. */
105
191
  select(v: View, opts?: ProjectOptions): Record[];
192
+ /** The roles whose `see` a slot needs above member (12.6 role marks): none when members may see it. */
193
+ private marksFor;
106
194
  /** A view's projection for an audience (or a caller), with filter counts and a page. */
107
195
  project(name: string, opts?: ProjectOptions): Projection;
196
+ /** One record in one shape: a core shape's object, or the shape's slots with their role marks. */
197
+ private shaped;
198
+ /** A nested view's rows for a page record (12.1, 12.2 `of`): every page, in the view's order. */
199
+ private nestedRows;
200
+ /**
201
+ * Structured data (12.5): schema.org JSON-LD for the public from the kind's type per level (11.2) and
202
+ * each facet's `same-as` in the schema prefix; nothing for any other audience.
203
+ */
204
+ jsonld(r: Record, audience?: string): JsonObject | undefined;
205
+ private streams;
206
+ /** A view's version, as its stream names it. */
207
+ versionOf(name: string): string;
208
+ /** A new version of a view: its stream starts over at the next publish (12.6). */
209
+ revise(name: string, version: string): void;
210
+ /**
211
+ * The projection stream (12.6): the entries since the last publish of this view for this audience, one
212
+ * per row that is new or changed, and one removal per row that left. Numbered per view and audience; a
213
+ * new version of the view starts over at 1, its first entry marked `reset`.
214
+ */
215
+ stream(name: string, opts?: Omit<ProjectOptions, "page" | "picks">): StreamEntry[];
216
+ /** The current version's entries after `seq`, for an index resuming from its cursor (12.6.2). */
217
+ entriesSince(name: string, seq: number, audience?: string): StreamEntry[];
108
218
  /** The portable shape (12.1): key, label, type and value for every value the audience may see. */
109
219
  portable(r: Record, audience?: string, caller?: Record): Json[];
110
220
  /** The keys a view reads (12.6), with level prefixes kept. */