@plitzi/sdk-schema 0.33.2 → 0.34.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @plitzi/sdk-schema
2
2
 
3
+ ## 0.34.1
4
+
5
+ ### Patch Changes
6
+
7
+ - v0.34.1
8
+ - Updated dependencies
9
+ - @plitzi/sdk-shared@0.34.1
10
+ - @plitzi/sdk-style@0.34.1
11
+
12
+ ## 0.34.0
13
+
14
+ ### Minor Changes
15
+
16
+ - v0.34.0
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [5aceda0]
21
+ - Updated dependencies
22
+ - Updated dependencies [5aceda0]
23
+ - @plitzi/sdk-shared@0.34.0
24
+ - @plitzi/sdk-style@0.34.0
25
+
3
26
  ## 0.33.2
4
27
 
5
28
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { Element, PageFolder, Schema, SchemaVariable, DropPosition, Style } from '@plitzi/sdk-shared';
1
+ import { Element, PageFolder, ReducerActionOrigin, Schema, SchemaVariable, DropPosition, Style } from '@plitzi/sdk-shared';
2
2
  export declare const SchemaActions: {
3
3
  readonly SCHEMA_UPDATE: "SCHEMA_UPDATE";
4
4
  readonly SCHEMA_ADD_PAGE: "SCHEMA_ADD_PAGE";
@@ -16,13 +16,12 @@ export declare const SchemaActions: {
16
16
  readonly SCHEMA_MOVE_ELEMENT: "SCHEMA_MOVE_ELEMENT";
17
17
  readonly SCHEMA_CLONE_ELEMENT: "SCHEMA_CLONE_ELEMENT";
18
18
  readonly SCHEMA_UPDATE_ELEMENT: "SCHEMA_UPDATE_ELEMENT";
19
+ readonly SCHEMA_RENAME_ELEMENT: "SCHEMA_RENAME_ELEMENT";
19
20
  readonly SCHEMA_UPDATE_ELEMENTS: "SCHEMA_UPDATE_ELEMENTS";
20
21
  readonly SCHEMA_ADD_TEMPLATE: "SCHEMA_ADD_TEMPLATE";
21
22
  readonly SCHEMA_UPDATE_SETTINGS: "SCHEMA_UPDATE_SETTINGS";
22
23
  };
23
- export type SchemaReducerActionsBase = {
24
- fromSubscriptions?: boolean;
25
- };
24
+ export type SchemaReducerActionsBase = ReducerActionOrigin;
26
25
  export type SchemaReducerActions = SchemaReducerActionsBase & ({
27
26
  type: 'SCHEMA_UPDATE';
28
27
  schema: Schema;
@@ -82,6 +81,10 @@ export type SchemaReducerActions = SchemaReducerActionsBase & ({
82
81
  } | {
83
82
  type: 'SCHEMA_UPDATE_ELEMENT';
84
83
  element: Element;
84
+ } | {
85
+ type: 'SCHEMA_RENAME_ELEMENT';
86
+ elementId: string;
87
+ id: string;
85
88
  } | {
86
89
  type: 'SCHEMA_UPDATE_ELEMENTS';
87
90
  elements: Element[];
@@ -1,8 +1,13 @@
1
- import e from "./helpers/FlatMap.mjs";
2
- import { get as t, has as n, set as r } from "@plitzi/plitzi-ui/helpers";
3
- import { produce as i } from "immer";
1
+ import { remapCollidingIds as e, takenIds as t } from "./helpers/elementId.mjs";
2
+ import n from "./helpers/FlatMap.mjs";
3
+ import { get as r, has as i, set as a } from "@plitzi/plitzi-ui/helpers";
4
+ import { produce as o } from "immer";
4
5
  //#region src/SchemaReducer.ts
5
- var a = {
6
+ var s = (e, t) => {
7
+ if (t.length === 0) return;
8
+ let n = t.filter((t) => e.variables && !e.variables.find((e) => e.name === t.name));
9
+ a(e, "variables", [...e.variables ?? [], ...n]);
10
+ }, c = {
6
11
  SCHEMA_UPDATE: "SCHEMA_UPDATE",
7
12
  SCHEMA_ADD_PAGE: "SCHEMA_ADD_PAGE",
8
13
  SCHEMA_HOME_PAGE: "SCHEMA_HOME_PAGE",
@@ -19,134 +24,147 @@ var a = {
19
24
  SCHEMA_MOVE_ELEMENT: "SCHEMA_MOVE_ELEMENT",
20
25
  SCHEMA_CLONE_ELEMENT: "SCHEMA_CLONE_ELEMENT",
21
26
  SCHEMA_UPDATE_ELEMENT: "SCHEMA_UPDATE_ELEMENT",
27
+ SCHEMA_RENAME_ELEMENT: "SCHEMA_RENAME_ELEMENT",
22
28
  SCHEMA_UPDATE_ELEMENTS: "SCHEMA_UPDATE_ELEMENTS",
23
29
  SCHEMA_ADD_TEMPLATE: "SCHEMA_ADD_TEMPLATE",
24
30
  SCHEMA_UPDATE_SETTINGS: "SCHEMA_UPDATE_SETTINGS"
25
- }, o = (o, s) => {
26
- switch (s.type) {
27
- case a.SCHEMA_UPDATE: return {
28
- ...o,
29
- ...s.schema
31
+ }, l = (l, u) => {
32
+ switch (u.type) {
33
+ case c.SCHEMA_UPDATE: return {
34
+ ...l,
35
+ ...u.schema
30
36
  };
31
- case a.SCHEMA_ADD_PAGE: {
32
- let { page: e } = s;
33
- return i(o, (t) => {
34
- r(t, "flat", {
37
+ case c.SCHEMA_ADD_PAGE: {
38
+ let { page: e } = u;
39
+ return o(l, (t) => {
40
+ a(t, "flat", {
35
41
  ...t.flat,
36
42
  [e.id]: e
37
43
  }), t.pages.push(e.id);
38
44
  });
39
45
  }
40
- case a.SCHEMA_HOME_PAGE: {
41
- let { flat: e, pages: n } = o, { pageId: a } = s, c;
42
- return n.forEach((n) => {
43
- if (c) return;
44
- let r = e[n];
45
- t(r, "attributes.default", !1) && (c = r);
46
- }), c ? i(o, (e) => {
47
- r(e.flat, `${a}.attributes.default`, !0), r(e.flat, `${c.id}.attributes.default`, !1);
48
- }) : i(o, (e) => {
49
- r(e.flat, `${a}.attributes.default`, !0);
46
+ case c.SCHEMA_HOME_PAGE: {
47
+ let { flat: e, pages: t } = l, { pageId: n } = u, i;
48
+ return t.forEach((t) => {
49
+ if (i) return;
50
+ let n = e[t];
51
+ r(n, "attributes.default", !1) && (i = n);
52
+ }), i ? o(l, (e) => {
53
+ a(e.flat, `${n}.attributes.default`, !0), a(e.flat, `${i.id}.attributes.default`, !1);
54
+ }) : o(l, (e) => {
55
+ a(e.flat, `${n}.attributes.default`, !0);
50
56
  });
51
57
  }
52
- case a.SCHEMA_UPDATE_PAGE: {
53
- let { page: e } = s;
54
- return i(o, (t) => {
55
- r(t.flat, e.id, e);
58
+ case c.SCHEMA_UPDATE_PAGE: {
59
+ let { page: e } = u;
60
+ return o(l, (t) => {
61
+ a(t.flat, e.id, e);
56
62
  });
57
63
  }
58
- case a.SCHEMA_REMOVE_PAGE: {
59
- let { pageId: t } = s;
60
- return i(o, (n) => {
61
- e.removeElement(n.flat, t, !0), n.pages = n.pages.filter((e) => e !== t);
64
+ case c.SCHEMA_REMOVE_PAGE: {
65
+ let { pageId: e } = u;
66
+ return o(l, (t) => {
67
+ n.removeElement(t.flat, e, !0), t.pages = t.pages.filter((t) => t !== e);
62
68
  });
63
69
  }
64
- case a.SCHEMA_ADD_PAGE_FOLDER: {
65
- let { pageFolder: e } = s;
66
- return i(o, (t) => {
70
+ case c.SCHEMA_ADD_PAGE_FOLDER: {
71
+ let { pageFolder: e } = u;
72
+ return o(l, (t) => {
67
73
  t.pageFolders.push(e);
68
74
  });
69
75
  }
70
- case a.SCHEMA_UPDATE_PAGE_FOLDER: {
71
- let { pageFolder: e } = s;
72
- return i(o, (t) => {
76
+ case c.SCHEMA_UPDATE_PAGE_FOLDER: {
77
+ let { pageFolder: e } = u;
78
+ return o(l, (t) => {
73
79
  let n = t.pageFolders.findIndex((t) => t.id === e.id);
74
80
  n !== -1 && (t.pageFolders[n] = e);
75
81
  });
76
82
  }
77
- case a.SCHEMA_REMOVE_PAGE_FOLDER: {
78
- let { pageFolderId: e } = s;
79
- return i(o, (t) => {
83
+ case c.SCHEMA_REMOVE_PAGE_FOLDER: {
84
+ let { pageFolderId: e } = u;
85
+ return o(l, (t) => {
80
86
  t.pageFolders = t.pageFolders.filter((t) => t.id !== e);
81
87
  });
82
88
  }
83
- case a.SCHEMA_ADD_VARIABLE: {
84
- let { variable: e } = s;
85
- return i(o, (t) => {
89
+ case c.SCHEMA_ADD_VARIABLE: {
90
+ let { variable: e } = u;
91
+ return o(l, (t) => {
86
92
  t.variables ||= [], t.variables.push(e);
87
93
  });
88
94
  }
89
- case a.SCHEMA_UPDATE_VARIABLE: {
90
- let { variable: e } = s;
91
- return o.variables ? i(o, (t) => {
95
+ case c.SCHEMA_UPDATE_VARIABLE: {
96
+ let { variable: e } = u;
97
+ return l.variables ? o(l, (t) => {
92
98
  let n = t.variables.findIndex((t) => t.name === e.name);
93
99
  t.variables[n] && (t.variables[n] = e);
94
- }) : o;
100
+ }) : l;
95
101
  }
96
- case a.SCHEMA_REMOVE_VARIABLE: {
97
- let { name: e } = s;
98
- return o.variables ? i(o, (t) => {
102
+ case c.SCHEMA_REMOVE_VARIABLE: {
103
+ let { name: e } = u;
104
+ return l.variables ? o(l, (t) => {
99
105
  t.variables = t.variables.filter((t) => t.name !== e);
100
- }) : o;
106
+ }) : l;
101
107
  }
102
- case a.SCHEMA_ADD_TEMPLATE:
103
- case a.SCHEMA_ADD_ELEMENT: {
104
- let { to: t, data: n, dropPosition: a, initialItems: c, variables: l = [] } = s;
105
- return i(o, (i) => {
106
- if (e.addElement(i.flat, n, t, a, c), l.length > 0) {
107
- let e = l.filter((e) => i.variables && !i.variables.find((t) => t.name === e.name));
108
- r(i, "variables", [...i.variables ?? [], ...e]);
109
- }
108
+ case c.SCHEMA_ADD_ELEMENT: {
109
+ let { to: e, data: t, dropPosition: r, initialItems: i, variables: a = [] } = u;
110
+ return o(l, (o) => {
111
+ n.addElement(o.flat, t, e, r, i), s(o, a);
110
112
  });
111
113
  }
112
- case a.SCHEMA_REMOVE_ELEMENT: {
113
- let { elementId: t } = s;
114
- return i(o, (n) => {
115
- e.removeElement(n.flat, t);
114
+ case c.SCHEMA_ADD_TEMPLATE: {
115
+ let { to: r, data: i, dropPosition: a, initialItems: c, variables: d = [] } = u;
116
+ return o(l, (o) => {
117
+ let l = structuredClone({
118
+ [i.id]: i,
119
+ ...c
120
+ }), u = t(o.flat), f = e(l, (e) => u.has(e))[i.id] ?? i.id, { [f]: p, ...m } = l;
121
+ n.addElement(o.flat, p, r, a, m), s(o, d);
116
122
  });
117
123
  }
118
- case a.SCHEMA_MOVE_ELEMENT: {
119
- let { from: t, to: n, elementId: r, dropPosition: a } = s;
120
- return i(o, (i) => {
121
- e.moveElement(i.flat, t, n, r, a);
124
+ case c.SCHEMA_REMOVE_ELEMENT: {
125
+ let { elementId: e } = u;
126
+ return o(l, (t) => {
127
+ n.removeElement(t.flat, e);
122
128
  });
123
129
  }
124
- case a.SCHEMA_CLONE_ELEMENT: {
125
- let { to: t, data: n, dropPosition: r, initialItems: a } = s;
126
- return i(o, (i) => {
127
- e.addElement(i.flat, n, t, r, a);
130
+ case c.SCHEMA_MOVE_ELEMENT: {
131
+ let { from: e, to: t, elementId: r, dropPosition: i } = u;
132
+ return o(l, (a) => {
133
+ n.moveElement(a.flat, e, t, r, i);
128
134
  });
129
135
  }
130
- case a.SCHEMA_UPDATE_ELEMENT: {
131
- let { element: t } = s;
132
- return i(o, (n) => {
133
- e.updateElement(n.flat, t);
136
+ case c.SCHEMA_CLONE_ELEMENT: {
137
+ let { to: e, data: t, dropPosition: r, initialItems: i } = u;
138
+ return o(l, (a) => {
139
+ n.addElement(a.flat, t, e, r, i);
134
140
  });
135
141
  }
136
- case a.SCHEMA_UPDATE_ELEMENTS: {
137
- let { elements: t } = s;
138
- return i(o, (n) => {
139
- t.forEach((t) => e.updateElement(n.flat, t));
142
+ case c.SCHEMA_UPDATE_ELEMENT: {
143
+ let { element: e } = u;
144
+ return o(l, (t) => {
145
+ n.updateElement(t.flat, e);
140
146
  });
141
147
  }
142
- case a.SCHEMA_UPDATE_SETTINGS: {
143
- let { path: e, value: t } = s;
144
- return i(o, (i) => {
145
- e && n(o.settings, e) ? r(i.settings, e, t) : e || r(i, "settings", t);
148
+ case c.SCHEMA_RENAME_ELEMENT: {
149
+ let { elementId: e, id: t } = u;
150
+ return o(l, (r) => {
151
+ n.renameElement(r, e, t);
146
152
  });
147
153
  }
148
- default: return o;
154
+ case c.SCHEMA_UPDATE_ELEMENTS: {
155
+ let { elements: e } = u;
156
+ return o(l, (t) => {
157
+ e.forEach((e) => n.updateElement(t.flat, e));
158
+ });
159
+ }
160
+ case c.SCHEMA_UPDATE_SETTINGS: {
161
+ let { path: e, value: t } = u;
162
+ return o(l, (n) => {
163
+ e && i(l.settings, e) ? a(n.settings, e, t) : e || a(n, "settings", t);
164
+ });
165
+ }
166
+ default: return l;
149
167
  }
150
168
  };
151
169
  //#endregion
152
- export { a as SchemaActions, o as default };
170
+ export { c as SchemaActions, l as default };
@@ -1,29 +1,69 @@
1
1
  import { SchemaValidationResult } from './schemaValidator';
2
+ import { MintElementId } from './elementId';
2
3
  import { Style, Element, Schema, DropPosition, SchemaVariable } from '@plitzi/sdk-shared';
4
+ /** An element on its way in. Its id is the name it will answer to, and leaving it out asks this map to mint one. */
5
+ export type ElementInput = Omit<Element, 'id'> & {
6
+ id?: Element['id'];
7
+ };
3
8
  export type FlatMapProps = {
4
9
  flat?: Schema['flat'];
5
10
  variables?: Schema['variables'];
11
+ /**
12
+ * The document's page list. Given, a page rename rewrites it too — a page renamed without it is a page the space
13
+ * no longer lists. Left out for a map that holds no pages (a segment, a template being cut).
14
+ */
15
+ pages?: Schema['pages'];
16
+ /**
17
+ * How an id is minted for an element nobody named. Defaults to the random minter, which is what a live document
18
+ * wants: the builder and the MCP write concurrently, and a counter has two writers pick the same name. An
19
+ * offline author or a test passes a positional one and gets output it can diff.
20
+ */
21
+ mintId?: MintElementId;
6
22
  };
7
23
  declare class FlatMap {
8
24
  flat: Schema['flat'];
9
25
  variables: Schema['variables'];
26
+ pages: Schema['pages'];
27
+ mintId: MintElementId;
10
28
  constructor(props?: FlatMapProps);
11
- addElement: (data: Element, to: Element["id"], dropPosition?: DropPosition, initialItems?: Record<Element["id"], Element>) => boolean;
12
- /** Refuses a rename onto an unusable idRef: two elements answering to the same name make every binding and
13
- * interaction written against it resolve to whichever one is found first. Only a change is checked, so an
14
- * element already stored with a bad ref stays editable.
15
- *
16
- * A rename that IS accepted carries its wiring with it: the idRef is the key bindings and interactions target,
17
- * so every reference to the old name across the space is repointed here. Doing it at the single point every
18
- * writer goes through is what keeps a rename from silently unwiring the element. */
29
+ /** A free id for a new element of `type`, minted through this map's minter and unique against what it holds. */
30
+ nextId: (type: string, alsoTaken?: (candidate: string) => boolean) => string;
31
+ /** Inserts an element, minting its id when the caller did not name it. Nothing else in the codebase mints an
32
+ * element id: every writer goes through here, so "every element has a name" is true by construction. */
33
+ addElement: (input: ElementInput, to: Element["id"], dropPosition?: DropPosition, initialItems?: Record<Element["id"], Element>) => boolean;
34
+ /** Replaces a stored element with an edited copy of itself. The id is its identity, not a field an update may
35
+ * carry a new value for — changing the name is `renameElement`, which is a document-wide operation. */
19
36
  updateElement: (element?: Element) => boolean;
37
+ /**
38
+ * Renames an element, carrying its wiring with it.
39
+ *
40
+ * The id IS the name — the `flat` key, what the tree points at, the `<type>_<id>` a binding reads and the target
41
+ * an interaction fires on — so a rename that only rewrote the key would silently unwire the element and every
42
+ * reference to it. `repointIds` rewrites all of them in one pass; doing it at the single point every writer goes
43
+ * through is what makes a readable id safe to change.
44
+ *
45
+ * Returns the ids of every element the rename touched (under their new names), which a caller broadcasting the
46
+ * change has to publish: the one element it renamed is almost never the whole of what moved.
47
+ */
48
+ renameElement: (from: Element["id"], to: Element["id"]) => Element["id"][] | false;
49
+ /** Why this element cannot be renamed to `id` (charset or a clash), or null when the name is free. */
50
+ renameConflict: (from: Element["id"], id: string) => string | null;
20
51
  moveElement: (from: Element["id"], to: Element["id"], elementId: Element["id"], dropPosition?: DropPosition) => boolean;
21
52
  getElement: (elementId: Element["id"]) => Element<Record<string, unknown>>;
22
- /** Every idRef currently in use, so a newly minted one stays unique across the space. */
23
- takenIdRefs: () => Set<string>;
24
- /** Why an idRef cannot be used here (charset or a clash), or null when it is free. `ignoreElementId` exempts the
25
- * element being edited, so re-saving an element its own ref is not a conflict. */
26
- idRefConflict: (idRef: string, ignoreElementId?: Element["id"]) => string | null;
53
+ /** Every id currently in use, so a newly minted one stays unique across the document. */
54
+ takenIds: () => Set<string>;
55
+ /** Why an id cannot be used here (charset or a clash), or null when it is free. `ignoreElementId` exempts the
56
+ * element being edited, so re-saving an element its own name is not a conflict. */
57
+ elementIdConflict: (id: string, ignoreElementId?: Element["id"]) => string | null;
58
+ /**
59
+ * Copies a subtree onto fresh names.
60
+ *
61
+ * Every id in the copy is minted here and every reference inside it repointed structurally, field by field. It is
62
+ * emphatically NOT a string replace over the serialized tree, which is what this used to be: that only ever
63
+ * worked because an id was 24 improbable hex characters, and with an id that reads like `hero` it would rewrite
64
+ * the word inside labels, prose, class names and content. References pointing OUT of the subtree are left alone,
65
+ * so a copy keeps reading the data source it was cloned next to.
66
+ */
27
67
  cloneElements: (elementId: Element["id"], parentId?: Element["id"], rootId?: Element["id"], excludeRoot?: boolean) => {
28
68
  acum: Record<Element["id"], Element>;
29
69
  item?: Element;
@@ -50,8 +90,9 @@ declare class FlatMap {
50
90
  assertValid: (context?: string) => void;
51
91
  getElementVariables: (style: Style, elementId: Element["id"], flat?: Record<string, Element<Record<string, unknown>>>, variables?: SchemaVariable[]) => SchemaVariable[];
52
92
  static getInstance: (props: FlatMapProps) => FlatMap;
53
- static addElement: (flat: Schema["flat"], data: Element, to: Element["id"], dropPosition?: DropPosition, initialItems?: Record<Element["id"], Element>) => boolean;
93
+ static addElement: (flat: Schema["flat"], data: ElementInput, to: Element["id"], dropPosition?: DropPosition, initialItems?: Record<Element["id"], Element>) => boolean;
54
94
  static updateElement: (flat: Schema["flat"], element: Element) => boolean;
95
+ static renameElement: (schema: Pick<Schema, "flat" | "pages">, from: Element["id"], to: Element["id"]) => false | string[];
55
96
  static moveElement: (flat: Schema["flat"], from: Element["id"], to: Element["id"], elementId: Element["id"], dropPosition?: DropPosition) => boolean;
56
97
  static getElement: (flat: Schema["flat"], elementId: Element["id"]) => Element<Record<string, unknown>>;
57
98
  static cloneElements: (flat: Schema["flat"], elementId: Element["id"], parentId?: Element["id"], rootId?: Element["id"], excludeRoot?: boolean) => {
@@ -59,8 +100,8 @@ declare class FlatMap {
59
100
  item?: Element;
60
101
  };
61
102
  static removeElement: (flat: Schema["flat"], elementId: Element["id"], removePage?: boolean) => boolean;
62
- static takenIdRefs: (flat: Schema["flat"]) => Set<string>;
63
- static idRefConflict: (flat: Schema["flat"], idRef: string, ignoreElementId?: Element["id"]) => string | null;
103
+ static takenIds: (flat: Schema["flat"]) => Set<string>;
104
+ static elementIdConflict: (flat: Schema["flat"], id: string, ignoreElementId?: Element["id"]) => string | null;
64
105
  static addVariables: (schemaVariables: Schema["variables"], variables: Schema["variables"]) => boolean;
65
106
  static addVariable: (schemaVariables: Schema["variables"], variable: SchemaVariable) => boolean;
66
107
  static updateVariable: (schemaVariables: Schema["variables"], variable: SchemaVariable) => boolean;