@peripheries/runtime 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.
package/README.md CHANGED
@@ -11,8 +11,13 @@ The contract between the host and federated component bundles
11
11
  `DocumentCellProps`, `WriteResult`, `Size`, `CellContext`).
12
12
  - **`config`**: the cell, page and structure configuration shapes.
13
13
  - **`graph`**: `NodeRecord`, the state names, and the traversal configuration.
14
+ - **`@peripheries/runtime/rank`** (its own entry): sibling order on
15
+ `graph_node.rank` (`compareRank`, `sortByRank`, `rankBetween`,
16
+ `initialRanks`, `rankAfterLast`, `minimalReRank`, `isValidRank`), over
17
+ `fractional-indexing`. For the host, scripts and the agency; components get
18
+ sorted data and don't import it.
14
19
 
15
- Types and plain data only. It replaces the component repos' scripts that copy
20
+ The main entry is types and plain data only. It replaces the component repos' scripts that copy
16
21
  host files by relative path.
17
22
 
18
23
  **Publishing:** on npm as `@peripheries/runtime`, built output only, with
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/config.ts","../src/graph.ts","../src/pinned.ts"],"mappings":";AAyGA,IAAa,gBAAgB;CAAC;CAAY;CAAW;CAAY;AAAW;;;ACtG5E,IAAa,cAAc;CAAC;CAAQ;CAAO;AAAK;AAChD,IAAa,cAAc;CAAC;CAAQ;CAAW;CAAS;AAAW;AASnE,IAAa,cAAc,YAAY,SAAS,MAAM,YAAY,KAAK,MAAM,GAAG,EAAE,GAAG,GAAgB,CAAC;AACtG,IAAa,gBAA2B;AACxC,IAAa,eAAe,MAA+B,OAAO,MAAM,YAAa,YAAyB,SAAS,CAAC;AAiExH,IAAa,gBAAgB;CAAE,WAAW;CAAY,UAAU;CAAG,UAAU;CAAI,iBAAiB;AAAI;;;ACpEtG,IAAa,wBAAwB;AAGrC,IAAa,iBAAiB;AAC9B,IAAa,wBAAwB;AAErC,IAAa,eAAe;AAC5B,IAAa,iBAAiB;AAS9B,IAAa,kBAAkB;CAC7B,OAAO;EAAE,SAAS;EAAW,KAAK;CAAoB;CACtD,qBAAqB;EAAE,SAAS;EAAW,KAAK;CAAgC;CAChF,yBAAyB;EAAE,SAAS;EAAW,KAAK;CAAoC;CACxF,aAAa;EAAE,SAAS;EAAW,KAAK;CAAwB;CAChE,oBAAoB;EAAE,SAAS;EAAW,KAAK;CAA+B;CAC9E,SAAS;EAAE,SAAS;EAAU,KAAK;CAAsB;CAEzD,gBAAgB;EAAE,SAAS;EAAK,KAAK;CAA0B;AACjE;AAKA,IAAa,oBAAsD,EACjE,aAAa,eACf;AAMA,IAAa,sBAAmG,EAC9G,gBAAgB;CAAE,OAAO;EAAC;EAAY;EAAc;EAAY;CAAW;CAAG,YAAY;AAAM,EAClG;AAUA,SAAgB,iBAAmC;CACjD,MAAM,UAAkC,CAAC;CACzC,MAAM,OAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,WAAW,QAAQ,OAAO,QAAQ,eAAe,GAAG;EAC9D,QAAQ,aAAa,IAAI;EACzB,KAAK,aAAa,IAAI;CACxB;CACA,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,iBAAiB,GAAG;EAC/D,QAAQ,SAAS,gBAAgB,OAAO,CAAC;EACzC,KAAK,SAAS,gBAAgB,OAAO,CAAC;CACxC;CACA,OAAO;EAAE,SAAS;EAAuB;EAAS;CAAK;AACzD"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/config.ts","../src/graph.ts","../src/pinned.ts"],"mappings":";AA0GA,IAAa,gBAAgB;CAAC;CAAY;CAAW;CAAY;AAAW;;;ACvG5E,IAAa,cAAc;CAAC;CAAQ;CAAO;AAAK;AAChD,IAAa,cAAc;CAAC;CAAQ;CAAW;CAAS;AAAW;AASnE,IAAa,cAAc,YAAY,SAAS,MAAM,YAAY,KAAK,MAAM,GAAG,EAAE,GAAG,GAAgB,CAAC;AACtG,IAAa,gBAA2B;AACxC,IAAa,eAAe,MAA+B,OAAO,MAAM,YAAa,YAAyB,SAAS,CAAC;AAiExH,IAAa,gBAAgB;CAAE,WAAW;CAAY,UAAU;CAAG,UAAU;CAAI,iBAAiB;AAAI;;;ACpEtG,IAAa,wBAAwB;AAGrC,IAAa,iBAAiB;AAC9B,IAAa,wBAAwB;AAErC,IAAa,eAAe;AAC5B,IAAa,iBAAiB;AAS9B,IAAa,kBAAkB;CAC7B,OAAO;EAAE,SAAS;EAAW,KAAK;CAAoB;CACtD,qBAAqB;EAAE,SAAS;EAAW,KAAK;CAAgC;CAChF,yBAAyB;EAAE,SAAS;EAAW,KAAK;CAAoC;CACxF,aAAa;EAAE,SAAS;EAAW,KAAK;CAAwB;CAChE,oBAAoB;EAAE,SAAS;EAAW,KAAK;CAA+B;CAC9E,SAAS;EAAE,SAAS;EAAU,KAAK;CAAsB;CAEzD,gBAAgB;EAAE,SAAS;EAAK,KAAK;CAA0B;AACjE;AAKA,IAAa,oBAAsD,EACjE,aAAa,eACf;AAMA,IAAa,sBAAmG,EAC9G,gBAAgB;CAAE,OAAO;EAAC;EAAY;EAAc;EAAY;CAAW;CAAG,YAAY;AAAM,EAClG;AAUA,SAAgB,iBAAmC;CACjD,MAAM,UAAkC,CAAC;CACzC,MAAM,OAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,WAAW,QAAQ,OAAO,QAAQ,eAAe,GAAG;EAC9D,QAAQ,aAAa,IAAI;EACzB,KAAK,aAAa,IAAI;CACxB;CACA,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,iBAAiB,GAAG;EAC/D,QAAQ,SAAS,gBAAgB,OAAO,CAAC;EACzC,KAAK,SAAS,gBAAgB,OAAO,CAAC;CACxC;CACA,OAAO;EAAE,SAAS;EAAuB;EAAS;CAAK;AACzD"}
package/dist/rank.js ADDED
@@ -0,0 +1,86 @@
1
+ import { generateKeyBetween, generateNKeysBetween } from "fractional-indexing";
2
+ //#region packages/runtime/src/rank.ts
3
+ var RANK_COLUMN = "rank";
4
+ function compareRank(a, b) {
5
+ const ra = a.rank ?? "";
6
+ const rb = b.rank ?? "";
7
+ if (!ra && rb) return 1;
8
+ if (ra && !rb) return -1;
9
+ if (ra !== rb) return ra < rb ? -1 : 1;
10
+ return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
11
+ }
12
+ function sortByRank(items, read) {
13
+ return items.slice().sort((x, y) => compareRank(read(x), read(y)));
14
+ }
15
+ function rankBetween(before, after, opts = {}) {
16
+ const key = generateKeyBetween(before ?? null, after ?? null);
17
+ if (!opts.jitter) return key;
18
+ const jittered = key + "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 61)];
19
+ return after && jittered >= after ? key : jittered;
20
+ }
21
+ function initialRanks(n) {
22
+ if (n <= 0) return [];
23
+ return generateNKeysBetween(null, null, n);
24
+ }
25
+ function rankAfterLast(existing) {
26
+ const keys = existing.filter((k) => !!k).sort();
27
+ return rankBetween(keys[keys.length - 1] ?? null, null);
28
+ }
29
+ function minimalReRank(orderedIds, currentRanks, opts = {}) {
30
+ const ranked = orderedIds.map((id) => ({
31
+ id,
32
+ rank: currentRanks[id] ?? null
33
+ }));
34
+ const n = ranked.length;
35
+ const best = new Array(n).fill(0);
36
+ const prev = new Array(n).fill(-1);
37
+ let bestEnd = -1;
38
+ for (let i = 0; i < n; i++) {
39
+ if (!ranked[i].rank) continue;
40
+ best[i] = 1;
41
+ for (let j = 0; j < i; j++) if (ranked[j].rank && ranked[j].rank < ranked[i].rank && best[j] + 1 > best[i]) {
42
+ best[i] = best[j] + 1;
43
+ prev[i] = j;
44
+ }
45
+ if (bestEnd === -1 || best[i] > best[bestEnd]) bestEnd = i;
46
+ }
47
+ const keep = new Set();
48
+ for (let i = bestEnd; i !== -1; i = prev[i]) keep.add(i);
49
+ const out = [];
50
+ const finalRanks = ranked.map((r, i) => keep.has(i) ? r.rank : null);
51
+ let i = 0;
52
+ while (i < n) {
53
+ if (keep.has(i)) {
54
+ i += 1;
55
+ continue;
56
+ }
57
+ let j = i;
58
+ while (j < n && !keep.has(j)) j += 1;
59
+ const before = i > 0 ? finalRanks[i - 1] : null;
60
+ const after = j < n ? finalRanks[j] : null;
61
+ const runLength = j - i;
62
+ const keys = runLength === 1 ? [rankBetween(before, after, opts)] : generateNKeysBetween(before, after, runLength);
63
+ for (let k = 0; k < runLength; k++) {
64
+ finalRanks[i + k] = keys[k];
65
+ out.push({
66
+ id: ranked[i + k].id,
67
+ rank: keys[k]
68
+ });
69
+ }
70
+ i = j;
71
+ }
72
+ return out;
73
+ }
74
+ function isValidRank(key) {
75
+ if (typeof key !== "string" || key.length === 0) return false;
76
+ try {
77
+ generateKeyBetween(key, null);
78
+ return true;
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
83
+ //#endregion
84
+ export { RANK_COLUMN, compareRank, initialRanks, isValidRank, minimalReRank, rankAfterLast, rankBetween, sortByRank };
85
+
86
+ //# sourceMappingURL=rank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rank.js","names":[],"sources":["../src/rank.ts"],"mappings":"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"}
@@ -97,7 +97,11 @@ export type PageCell = {
97
97
  traversal?: TraversalConfig;
98
98
  data?: CellData;
99
99
  bundle_ref?: unknown;
100
- actions?: Record<string, string>;
100
+ /** name → the mutation it means: `'pages.update'`, or `{ registry, entityKey }`. */
101
+ actions?: Record<string, string | {
102
+ registry: string;
103
+ entityKey?: string;
104
+ }>;
101
105
  selections?: SelectionDeclarations;
102
106
  viewState?: ViewStateDeclarations;
103
107
  live?: LiveDeclarations;
@@ -57,7 +57,7 @@ export interface TraversalConfig {
57
57
  direction?: 'incoming' | 'outgoing' | 'both';
58
58
  /** Required: the edge types the walk follows. */
59
59
  edgeTypes: string[];
60
- /** The walk enters only these types, so nothing past another type is reached. */
60
+ /** The walk enters only these types, so nothing past another type is reached. Empty or absent: no filter. */
61
61
  nodeTypes?: string[];
62
62
  /** Default 3. */
63
63
  maxDepth?: number;
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Where a node's order among its siblings lives: the `graph_node.rank` column.
3
+ *
4
+ * ── Why the membership row ──────────────────────────────────────────────────
5
+ *
6
+ * Order is GRAPH-SCOPED, so it belongs on the row representing a node's membership in
7
+ * a graph — not on the node. `graph_node` has no unique constraint on `node` (just a
8
+ * PK on `id` and three FKs), so the schema deliberately permits one node in several
9
+ * graphs; were membership 1:1, `node` would carry `graph` directly and this table
10
+ * would not exist. It happens to be 1:1 today (5,901 nodes, zero in more than one
11
+ * graph) but only because `duplicate_graph` clones fresh `node` rows per graph — a
12
+ * consequence of the clone strategy, not an invariant. "Order within what?" has no
13
+ * answer on a `node` row.
14
+ *
15
+ * Every other candidate was considered and rejected:
16
+ *
17
+ * `system_node_state` — a new NULL on the next append. Nothing carries state
18
+ * column or its existing metadata forward; each writer builds its own, and
19
+ * `metadata` jsonb `insertNodeState` names exactly seven columns.
20
+ * Measured on the worst node locally: 71 appends,
21
+ * 6 with metadata, 65 NULL, writers interleaved.
22
+ * DSNS `data.rank` Survives (writers spread `{ ...current }`), but
23
+ * state is append-only, so every drag appends a row,
24
+ * bumps the appraisal fingerprint, and tells the
25
+ * controller an objective changed because somebody
26
+ * reordered a list.
27
+ * `node.metadata.rank` Survives everything including the clone, but
28
+ * asserts that order is a property of the node.
29
+ * `graph_node.position.rank` Free and already cloned, but `position` is
30
+ * React-Flow canvas x/y. Nothing persists it today;
31
+ * the moment something does it will write `{x, y}`
32
+ * wholesale and silently delete every rank, with no
33
+ * reason to suspect list order was in there.
34
+ * `edge.metadata` / `graph_edge` The purest model — order among a parent's children
35
+ * is a property of that edge, and multi-parent is
36
+ * permitted. But the WRONG GRANULARITY for these
37
+ * lists: the backlog orders every feature in the
38
+ * walk filtered by kind, not one release's children,
39
+ * so two features under different releases would
40
+ * hold keys in incomparable namespaces. Cells also
41
+ * cannot read edge metadata today —
42
+ * `p_include_edge_metadata` defaults false and the
43
+ * host never passes it.
44
+ *
45
+ * One comparable namespace per graph, and each cell sorts within whatever filtered set
46
+ * it displays. If per-parent ordering is ever needed — an independently ordered
47
+ * "Scope" list on a release page — an edge-scoped key can be added alongside without
48
+ * migrating this one, because fractional keys only need to be comparable within the
49
+ * set being sorted.
50
+ *
51
+ * Rank is deliberately NOT state: nothing appraises it, nothing derives from it, no
52
+ * guard applies to it. It is presentation ordering on a mutable row.
53
+ */
54
+ export declare const RANK_COLUMN = "rank";
55
+ /**
56
+ * Compare two rank keys, falling back to the id.
57
+ *
58
+ * The tiebreaker is not decoration: two offline clients inserting at the same
59
+ * position produce the same key, and an unranked item has no key at all. Without a
60
+ * deterministic second term the list order flickers between renders.
61
+ *
62
+ * Deliberately `<` / `>` and NOT `localeCompare` — see the collation note above.
63
+ * A locale comparator would interleave case and scramble the order.
64
+ */
65
+ export declare function compareRank(a: {
66
+ rank?: string | null;
67
+ id: string;
68
+ }, b: {
69
+ rank?: string | null;
70
+ id: string;
71
+ }): number;
72
+ /** Sort into display order. Stable, and total even with missing or equal keys. */
73
+ export declare function sortByRank<T>(items: readonly T[], read: (item: T) => {
74
+ rank?: string | null;
75
+ id: string;
76
+ }): T[];
77
+ /**
78
+ * A key strictly between two neighbours. Either side may be null for "the end".
79
+ *
80
+ * `jitter` appends a random low-order character instead of taking the exact
81
+ * midpoint, which slows key growth under repeated inserts into one gap and makes
82
+ * two concurrent inserts less likely to collide. Off by default: it lengthens every
83
+ * key by one character, which is the wrong trade for the common single-drag case.
84
+ */
85
+ export declare function rankBetween(before: string | null | undefined, after: string | null | undefined, opts?: {
86
+ jitter?: boolean;
87
+ }): string;
88
+ /** `n` fresh keys for a sibling set that has none — the initial backfill. */
89
+ export declare function initialRanks(n: number): string[];
90
+ /** A key that appends after everything in `existing`. Use when creating a record. */
91
+ export declare function rankAfterLast(existing: ReadonlyArray<string | null | undefined>): string;
92
+ export interface RankAssignment {
93
+ id: string;
94
+ rank: string;
95
+ }
96
+ /**
97
+ * Given the order the user wants and the ranks that exist, return ONLY the items
98
+ * whose key has to change.
99
+ *
100
+ * This is what keeps a reorder to one write. The naive implementation reassigns
101
+ * every sibling — N state rows per drag, which is exactly what D3d forbids and
102
+ * would also bump N appraisal fingerprints for a cosmetic change.
103
+ *
104
+ * Minimal by construction: it keeps the longest subsequence of items whose current
105
+ * keys are ALREADY in the desired relative order, and re-keys only the rest,
106
+ * generating each run of changed items between the two kept anchors that bracket
107
+ * it. For a single drag that is exactly one item. Items with no key are always
108
+ * assigned, which is how the lazy first-reorder backfill happens.
109
+ *
110
+ * Equal keys count as out of order, so a collision from two offline clients heals
111
+ * on the next reorder rather than persisting as a flickering list.
112
+ */
113
+ export declare function minimalReRank(orderedIds: readonly string[], currentRanks: Readonly<Record<string, string | null | undefined>>, opts?: {
114
+ jitter?: boolean;
115
+ }): RankAssignment[];
116
+ /**
117
+ * Is this a well-formed key? For validating one that arrived from outside the host.
118
+ *
119
+ * DELEGATES to the generator rather than re-checking the invariant, and that is the
120
+ * point. The obvious implementation — reject anything ending in the lowest
121
+ * character — is WRONG, and wrong in a way that passes casual review: the invariant
122
+ * applies to the FRACTIONAL part, but the first character is a length marker, so
123
+ * "a0" is integer 0 with no fraction and is perfectly valid, while "a10" is integer
124
+ * 1 with a redundant trailing-zero fraction and is not. Telling those apart means
125
+ * decoding the length marker — exactly the fiddly edge case that argues for using a
126
+ * tested generator instead of hand-rolling one. `generateKeyBetween` already runs
127
+ * the real validator on its inputs, so asking it is both shorter and correct.
128
+ */
129
+ export declare function isValidRank(key: unknown): key is string;
package/package.json CHANGED
@@ -1,19 +1,26 @@
1
1
  {
2
2
  "name": "@peripheries/runtime",
3
- "version": "0.1.0",
4
- "description": "The host's runtime contract for federated component bundles: pinned shared specifiers, the import map, and the types of what a cell component receives.",
3
+ "version": "0.3.0",
4
+ "description": "The host's runtime contract for federated component bundles: pinned shared specifiers, the import map, the types of what a cell component receives, and sibling order (`/rank`).",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "exports": {
8
8
  ".": {
9
9
  "types": "./dist/types/index.d.ts",
10
10
  "default": "./dist/index.js"
11
+ },
12
+ "./rank": {
13
+ "types": "./dist/types/rank.d.ts",
14
+ "default": "./dist/rank.js"
11
15
  }
12
16
  },
13
17
  "files": [
14
18
  "dist",
15
19
  "README.md"
16
20
  ],
21
+ "dependencies": {
22
+ "fractional-indexing": "4.0.0"
23
+ },
17
24
  "license": "UNLICENSED",
18
25
  "repository": {
19
26
  "type": "git",