@plitzi/sdk-shared 0.37.2 → 0.37.3
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 +1146 -0
- package/dist/actions/access.d.ts +12 -0
- package/dist/actions/access.mjs +13 -0
- package/dist/actions/functions.d.ts +27 -0
- package/dist/actions/functions.mjs +18 -0
- package/dist/actions/index.d.ts +4 -0
- package/dist/actions/index.mjs +9 -7
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.mjs +2 -1
- package/dist/auth/visitorRoles.d.ts +27 -0
- package/dist/auth/visitorRoles.mjs +48 -0
- package/dist/authoring/builder.mjs +1 -0
- package/dist/authoring/declare.d.ts +53 -0
- package/dist/authoring/declare.mjs +2 -2
- package/dist/authoring/index.mjs +5 -5
- package/dist/authoring/paramSpec.d.ts +1 -1
- package/dist/authoring/paramSpec.mjs +1 -0
- package/dist/authoring/spaceCallbacks.mjs +2 -2
- package/dist/dataSource/computed.d.ts +21 -0
- package/dist/dataSource/computed.mjs +45 -0
- package/dist/dataSource/getBindingsDetails.mjs +35 -34
- package/dist/dataSource/index.d.ts +1 -0
- package/dist/dataSource/index.mjs +7 -6
- package/dist/dataSource/utility/not.mjs +4 -7
- package/dist/dataSource/utility/stringToArray.mjs +1 -1
- package/dist/dataSource/utility/truthiness.d.ts +1 -0
- package/dist/dataSource/utility/truthiness.mjs +8 -0
- package/dist/dataSource/utility/twigTemplate.d.ts +2 -1
- package/dist/dataSource/utility/twigTemplate.mjs +29 -17
- package/dist/devTools/utils/PlitziConsole.mjs +22 -22
- package/dist/helpers/cookies.d.ts +10 -0
- package/dist/helpers/cookies.mjs +19 -0
- package/dist/helpers/fetchManifest.d.ts +9 -0
- package/dist/helpers/fetchManifest.mjs +3 -6
- package/dist/helpers/formatDate.d.ts +5 -3
- package/dist/helpers/formatDate.mjs +34 -36
- package/dist/helpers/index.d.ts +2 -0
- package/dist/helpers/index.mjs +18 -14
- package/dist/helpers/isDate.d.ts +7 -0
- package/dist/helpers/isDate.mjs +15 -0
- package/dist/helpers/keys.d.ts +42 -0
- package/dist/helpers/keys.mjs +91 -0
- package/dist/helpers/twigWrapper/AST.d.ts +2 -2
- package/dist/helpers/twigWrapper/Evaluator/Evaluator.d.ts +12 -2
- package/dist/helpers/twigWrapper/Evaluator/Evaluator.mjs +57 -34
- package/dist/helpers/twigWrapper/Evaluator/index.d.ts +1 -1
- package/dist/helpers/twigWrapper/Evaluator/index.mjs +2 -2
- package/dist/helpers/twigWrapper/Parser/ExpressionParser.d.ts +2 -2
- package/dist/helpers/twigWrapper/Parser/ExpressionParser.mjs +147 -34
- package/dist/helpers/twigWrapper/Parser/Parser.d.ts +2 -1
- package/dist/helpers/twigWrapper/Parser/Parser.mjs +21 -20
- package/dist/helpers/twigWrapper/filters/filters.mjs +130 -112
- package/dist/helpers/twigWrapper/index.d.ts +5 -2
- package/dist/helpers/twigWrapper/index.mjs +7 -5
- package/dist/helpers/twigWrapper/inspectTemplate.d.ts +23 -0
- package/dist/helpers/twigWrapper/inspectTemplate.mjs +110 -0
- package/dist/helpers/twigWrapper/processTwig/helpers.d.ts +7 -0
- package/dist/helpers/twigWrapper/processTwig/helpers.mjs +2 -1
- package/dist/helpers/twigWrapper/processTwig/index.d.ts +2 -1
- package/dist/helpers/twigWrapper/processTwig/index.mjs +3 -2
- package/dist/helpers/twigWrapper/processTwig/processTwig.d.ts +28 -0
- package/dist/helpers/twigWrapper/processTwig/processTwig.mjs +73 -16
- package/dist/helpers/twigWrapper/processTwig/resolveStepParam.d.ts +17 -0
- package/dist/helpers/twigWrapper/processTwig/resolveStepParam.mjs +14 -0
- package/dist/helpers/twigWrapper/templateRoots.d.ts +11 -0
- package/dist/helpers/twigWrapper/templateRoots.mjs +4 -4
- package/dist/helpers/twigWrapper/tokens/hasTemplateSyntax.d.ts +1 -1
- package/dist/history/describe.d.ts +29 -0
- package/dist/history/describe.mjs +93 -0
- package/dist/history/diff.d.ts +33 -0
- package/dist/history/diff.mjs +73 -0
- package/dist/history/index.d.ts +3 -0
- package/dist/history/index.mjs +3 -0
- package/dist/history/types.d.ts +48 -0
- package/dist/history/types.mjs +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +77 -66
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.mjs +2 -2
- package/dist/navigation/routes.d.ts +11 -1
- package/dist/navigation/routes.mjs +15 -10
- package/dist/network/graphql/builder/Mutations/Space/SpaceFixIssuesMutation.d.ts +14 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceFixIssuesMutation.mjs +16 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdatePluginMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdatePluginMutation.mjs +2 -2
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRunActionMutation.mjs +1 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceRemoveFunctionsMutation.d.ts +3 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceRemoveFunctionsMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceSaveFunctionsMutation.d.ts +11 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceSaveFunctionsMutation.mjs +24 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceTryFunctionMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceTryFunctionMutation.mjs +15 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeVariableMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeVariableMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeSizeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeSizeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeVariableMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeVariableMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStartRuntimeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStartRuntimeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStopRuntimeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStopRuntimeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceAddVisitorMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceAddVisitorMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceRemoveVisitorMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceRemoveVisitorMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/index.d.ts +28 -0
- package/dist/network/graphql/builder/Mutations/index.mjs +108 -84
- package/dist/network/graphql/builder/Queries/Space/SpaceChangesQuery.d.ts +23 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceChangesQuery.mjs +49 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceFunctionsQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceFunctionsQuery.mjs +13 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.d.ts +17 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.mjs +22 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceRuntimeQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceRuntimeQuery.mjs +32 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceVisitorsQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceVisitorsQuery.mjs +16 -0
- package/dist/network/graphql/builder/Queries/index.d.ts +17 -3
- package/dist/network/graphql/builder/Queries/index.mjs +30 -22
- package/dist/network/graphql/sdk/Mutations/index.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/InitQuery.mjs +2 -91
- package/dist/network/graphql/sdk/Queries/Segment/SegmentQuery.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/Segment/SegmentQuery.mjs +2 -44
- package/dist/network/graphql/sdk/Queries/Segment/SegmentsQuery.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/Segment/SegmentsQuery.mjs +2 -55
- package/dist/network/graphql/sdk/Queries/index.d.ts +1 -5
- package/dist/network/index.mjs +7 -7
- package/dist/network/spaceEvents.d.ts +33 -3
- package/dist/network/spaceEvents.mjs +102 -89
- package/dist/realtime/client.d.ts +46 -0
- package/dist/realtime/client.mjs +192 -0
- package/dist/realtime/index.d.ts +6 -0
- package/dist/realtime/index.mjs +4 -0
- package/dist/realtime/presence.d.ts +38 -0
- package/dist/realtime/presence.mjs +70 -0
- package/dist/realtime/topics.d.ts +36 -0
- package/dist/realtime/topics.mjs +25 -0
- package/dist/server/actions/useRealtimeSync.d.ts +9 -0
- package/dist/server/actions/useRealtimeSync.mjs +7 -0
- package/dist/state/index.d.ts +1 -0
- package/dist/state/index.mjs +3 -2
- package/dist/state/paintedState.d.ts +52 -0
- package/dist/state/paintedState.mjs +37 -0
- package/dist/state/runtimeStatePersist.d.ts +8 -1
- package/dist/state/runtimeStatePersist.mjs +79 -29
- package/dist/store/index.d.ts +45 -45
- package/dist/store/renderSettings.d.ts +6 -3
- package/dist/store/tracing/index.d.ts +1 -0
- package/dist/store/tracing/tracingCollector.d.ts +17 -1
- package/dist/store/tracing/tracingCollector.mjs +5 -0
- package/dist/style/index.d.ts +1 -0
- package/dist/style/index.mjs +3 -2
- package/dist/style/runtimeStyle.d.ts +29 -0
- package/dist/style/runtimeStyle.mjs +7 -0
- package/dist/style/styleConstants.d.ts +3 -2
- package/dist/style/styleConstants.mjs +2 -0
- package/dist/style/styleStates.d.ts +14 -1
- package/dist/style/styleStates.mjs +10 -7
- package/dist/theme/ThemeProvider.mjs +35 -29
- package/dist/theme/themeCookie.mjs +11 -15
- package/dist/types/ActionTypes.d.ts +4 -0
- package/dist/types/AuthTypes.d.ts +11 -1
- package/dist/types/CommonTypes.d.ts +6 -0
- package/dist/types/FunctionTypes.d.ts +52 -0
- package/dist/types/FunctionTypes.mjs +0 -0
- package/dist/types/PluginTypes.d.ts +0 -1
- package/dist/types/RealtimeTypes.d.ts +94 -0
- package/dist/types/RealtimeTypes.mjs +0 -0
- package/dist/types/SchemaTypes.d.ts +54 -0
- package/dist/types/SchemaTypes.mjs +8 -0
- package/dist/types/ServerTypes.d.ts +259 -15
- package/dist/types/SpaceTypes.d.ts +53 -0
- package/dist/types/StateTypes.d.ts +6 -0
- package/dist/types/StoreTypes.d.ts +11 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.mjs +3 -2
- package/package.json +172 -11
- package/vite.config.ts +0 -12
- package/dist/network/graphql/builder/Queries/PluginsQuery.d.ts +0 -9
- package/dist/network/graphql/builder/Queries/PluginsQuery.mjs +0 -54
|
@@ -1,24 +1,81 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { getNodes as
|
|
1
|
+
import { finalizeRaw as e, flattenContext as t, renderSimpleTokens as n } from "./helpers.mjs";
|
|
2
|
+
import { evaluate as r, evaluateExpression as i } from "../Evaluator/Evaluator.mjs";
|
|
3
|
+
import { getNodes as a, resolveTokens as o } from "../TemplateCache/TemplateCache.mjs";
|
|
4
4
|
//#region src/helpers/twigWrapper/processTwig/processTwig.ts
|
|
5
|
-
var
|
|
6
|
-
if (typeof
|
|
5
|
+
var s = (i, s = {}, c = !1, l = !1) => {
|
|
6
|
+
if (typeof i != "string") return i;
|
|
7
7
|
try {
|
|
8
|
-
if (
|
|
9
|
-
let u = "variables" in s ?
|
|
10
|
-
if (!d) return
|
|
8
|
+
if (i.indexOf("{%") === -1 && i.indexOf("{{") === -1) return i;
|
|
9
|
+
let u = "variables" in s ? t(s) : s, d = o(i);
|
|
10
|
+
if (!d) return i;
|
|
11
11
|
if (!c && !d.hasTags && d.allSimpleOrDotted) {
|
|
12
|
-
let
|
|
13
|
-
return l ? t
|
|
12
|
+
let t = n(d, u);
|
|
13
|
+
return l ? e(t) : t;
|
|
14
14
|
}
|
|
15
|
-
let f =
|
|
16
|
-
if (!f) return
|
|
17
|
-
let { output: p, variables: m, hasSet: h } =
|
|
18
|
-
return h && Object.assign(s, m), c && p ===
|
|
15
|
+
let f = a(d, c);
|
|
16
|
+
if (!f) return i;
|
|
17
|
+
let { output: p, variables: m, hasSet: h } = r(f, u, c);
|
|
18
|
+
return h && Object.assign(s, m), c && p === i ? i : l ? e(p) : p;
|
|
19
19
|
} catch {
|
|
20
|
-
return
|
|
20
|
+
return i;
|
|
21
|
+
}
|
|
22
|
+
}, c = (e) => {
|
|
23
|
+
let t = e.trimStart();
|
|
24
|
+
return t.startsWith("{") || t.startsWith("[");
|
|
25
|
+
}, l = (e, n) => {
|
|
26
|
+
let i = o(e), a = i ? i.nodes ?? i.nodesWithSource : null;
|
|
27
|
+
if (a) try {
|
|
28
|
+
let e = "variables" in n ? t(n) : n, { output: i, variables: o, hasSet: s } = r(a, e, !1, !0);
|
|
29
|
+
if (!c(i)) return;
|
|
30
|
+
let l = JSON.parse(i);
|
|
31
|
+
return s && Object.assign(n, o), l;
|
|
32
|
+
} catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}, u = (e, n = {}) => {
|
|
36
|
+
if (typeof e != "string") return e;
|
|
37
|
+
let r = o(e), a = (r ? r.nodes ?? r.nodesWithSource : null)?.filter((e) => e.type !== "text" || e.value.trim() !== "");
|
|
38
|
+
if (a?.length !== 1 || a[0].type !== "variable") return s(e, n);
|
|
39
|
+
try {
|
|
40
|
+
let e = "variables" in n ? t(n) : n;
|
|
41
|
+
return i(a[0].expression, e);
|
|
42
|
+
} catch {
|
|
43
|
+
return e;
|
|
44
|
+
}
|
|
45
|
+
}, d = /* @__PURE__ */ new Set([
|
|
46
|
+
"json_encode",
|
|
47
|
+
"to_json",
|
|
48
|
+
"object_as_json"
|
|
49
|
+
]), f = (e) => e.type === "filter" && d.has(e.filters[e.filters.length - 1]?.name ?? ""), p = (e) => {
|
|
50
|
+
let t = e.trim();
|
|
51
|
+
if (!t.startsWith("{") && !t.startsWith("[")) return e;
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(t);
|
|
54
|
+
} catch {
|
|
55
|
+
return e;
|
|
56
|
+
}
|
|
57
|
+
}, m = (e, n = {}) => {
|
|
58
|
+
if (typeof e != "string") return e;
|
|
59
|
+
let r = o(e), a = (r ? r.nodes ?? r.nodesWithSource : null)?.filter((e) => e.type !== "text" || e.value.trim() !== "");
|
|
60
|
+
if (a?.length !== 1 || a[0].type !== "variable") {
|
|
61
|
+
let t = e.includes("\"") ? l(e, n) : void 0;
|
|
62
|
+
if (t !== void 0) return t;
|
|
63
|
+
let r = s(e, n);
|
|
64
|
+
return typeof r == "string" ? p(r) : r;
|
|
65
|
+
}
|
|
66
|
+
let { expression: c } = a[0];
|
|
67
|
+
try {
|
|
68
|
+
let e = "variables" in n ? t(n) : n, r = i(c, e);
|
|
69
|
+
if (r === void 0) return "";
|
|
70
|
+
if (typeof r == "string" && f(c)) try {
|
|
71
|
+
return JSON.parse(r);
|
|
72
|
+
} catch {
|
|
73
|
+
return r;
|
|
74
|
+
}
|
|
75
|
+
return r;
|
|
76
|
+
} catch {
|
|
77
|
+
return e;
|
|
21
78
|
}
|
|
22
79
|
};
|
|
23
80
|
//#endregion
|
|
24
|
-
export {
|
|
81
|
+
export { s as processTwig, m as processTwigParam, u as processTwigValue };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** How many times a value may resolve to another template before the resolver stops and says so. */
|
|
2
|
+
export declare const MAX_PARAM_PASSES = 5;
|
|
3
|
+
/**
|
|
4
|
+
* One step param, resolved against the flow's scope — the ONE resolver for the browser's flows and a server action's
|
|
5
|
+
* steps, so a param means the same on both sides.
|
|
6
|
+
*
|
|
7
|
+
* The param as written is a template whatever it holds: a condition, a loop or an object literal as much as a name —
|
|
8
|
+
* which is why the first pass runs on any template syntax, not only on what `hasValidToken` recognises (it answers a
|
|
9
|
+
* narrower question, for attributes, where the text around a token is prose). The server used to skip that first pass,
|
|
10
|
+
* so `{{ { "id": run.id } }}` reached its task as the template text. What a pass RETURNS is data, and is read again only
|
|
11
|
+
* when it carries a well-formed token — so text a visitor typed that happens to contain braces is not evaluated — up to
|
|
12
|
+
* {@link MAX_PARAM_PASSES}. `unresolved` says the ceiling was hit with tokens left, for the caller to report.
|
|
13
|
+
*/
|
|
14
|
+
export declare const resolveStepParam: (template: string, scope: Record<string, unknown>) => {
|
|
15
|
+
value: unknown;
|
|
16
|
+
unresolved: boolean;
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { processTwigParam as e } from "./processTwig.mjs";
|
|
2
|
+
import { hasTemplateSyntax as t } from "../tokens/hasTemplateSyntax.mjs";
|
|
3
|
+
import { hasValidToken as n } from "../tokens/hasValidToken.mjs";
|
|
4
|
+
//#region src/helpers/twigWrapper/processTwig/resolveStepParam.ts
|
|
5
|
+
var r = 5, i = (r, i) => {
|
|
6
|
+
let a = r, o = 5;
|
|
7
|
+
for (t(a) && !n(r) && (a = e(r, i), o--); typeof a == "string" && n(a) && o > 0;) a = e(a, i), o--;
|
|
8
|
+
return {
|
|
9
|
+
value: a,
|
|
10
|
+
unresolved: typeof a == "string" && n(a)
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { r as MAX_PARAM_PASSES, i as resolveStepParam };
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every path a template reads, as far as it is known before it runs: `{{ computed.tool == 'pen' }}` gives
|
|
3
|
+
* `computed.tool`, `{{ state.owned[source.id] }}` gives `state.owned` and `source.id` — a bracket whose key is only
|
|
4
|
+
* known at run time ends the path at what came before it.
|
|
5
|
+
*
|
|
6
|
+
* What a caller SUBSCRIBES to, where the root alone would be too much: an element whose template reads
|
|
7
|
+
* `computed.tool` has no reason to render again when `computed.selectionCount` changes, and every element on a page
|
|
8
|
+
* reads some computed value. Names the template binds itself — a loop variable, a `set`, an arrow's parameter —
|
|
9
|
+
* come back too: they resolve to no source, and asking for a path that is not there costs nothing.
|
|
10
|
+
*/
|
|
11
|
+
export declare const templatePaths: (template: string) => string[];
|
|
1
12
|
/**
|
|
2
13
|
* Every top-level name a template reads: `{{ theme.resolved }}` and `{% if state.open %}` both give their first segment.
|
|
3
14
|
*
|
|
@@ -7,8 +7,8 @@ var t = (e, n) => {
|
|
|
7
7
|
}
|
|
8
8
|
if (typeof e == "object" && e) {
|
|
9
9
|
if ("type" in e && e.type === "path" && "segments" in e && Array.isArray(e.segments)) {
|
|
10
|
-
let t = e.segments
|
|
11
|
-
|
|
10
|
+
let t = e.segments.filter((e) => typeof e == "string");
|
|
11
|
+
t.length > 0 && n.add(t.join("."));
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
for (let r of Object.values(e)) t(r, n);
|
|
@@ -18,6 +18,6 @@ var t = (e, n) => {
|
|
|
18
18
|
if (!r) return [];
|
|
19
19
|
let i = /* @__PURE__ */ new Set();
|
|
20
20
|
return t(r.nodes ?? r.nodesWithSource, i), [...i];
|
|
21
|
-
};
|
|
21
|
+
}, r = (e) => [...new Set(n(e).map((e) => e.split(".")[0]))];
|
|
22
22
|
//#endregion
|
|
23
|
-
export { n as templateRootNames };
|
|
23
|
+
export { n as templatePaths, r as templateRootNames };
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* are templates by construction, so a condition (`{{ admin ? '1' : '' }}`) or a loop (`{% for %}…{% endfor %}`) is
|
|
7
7
|
* meant to run — read by the narrow test they were handed on as written, and a flag stored its own template text.
|
|
8
8
|
*/
|
|
9
|
-
export declare const hasTemplateSyntax: (value: unknown) =>
|
|
9
|
+
export declare const hasTemplateSyntax: (value: unknown) => boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ChangeEntry } from './types';
|
|
2
|
+
export type FieldChange = {
|
|
3
|
+
path: string;
|
|
4
|
+
before?: unknown;
|
|
5
|
+
after?: unknown;
|
|
6
|
+
};
|
|
7
|
+
/** What a line says was done, for a reader who scans the icon before the words. */
|
|
8
|
+
export type ChangeAction = 'add' | 'remove' | 'move' | 'update' | 'reorder';
|
|
9
|
+
/** One thing a save did, in words, and the element it is about when it is about one. */
|
|
10
|
+
export type ChangeLine = {
|
|
11
|
+
text: string;
|
|
12
|
+
action: ChangeAction;
|
|
13
|
+
elementId?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* What changed inside one entity, field by field (`attributes.content`, `definition.items`). Objects are walked; a list
|
|
17
|
+
* or a value is compared whole, since "the third item moved" reads worse than the list before and after.
|
|
18
|
+
*/
|
|
19
|
+
export declare const fieldChanges: (before: unknown, after: unknown, path?: string) => FieldChange[];
|
|
20
|
+
/** Each line once, the first time it is said. */
|
|
21
|
+
export declare const uniqueLines: (lines: ChangeLine[]) => ChangeLine[];
|
|
22
|
+
/**
|
|
23
|
+
* One save, as lines a person reads: each thing it did, said once and in words.
|
|
24
|
+
*
|
|
25
|
+
* Adding an element also rewrites its parent's list of children, and a move rewrites two; those are the consequence of
|
|
26
|
+
* the add or the move, so they are not said again. A parent whose children changed for no other reason in the same
|
|
27
|
+
* save — a reorder — is said as that.
|
|
28
|
+
*/
|
|
29
|
+
export declare const describeChange: (entries: ChangeEntry[]) => ChangeLine[];
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/history/describe.ts
|
|
2
|
+
var e = (e) => typeof e == "object" && !!e && !Array.isArray(e), t = (n, r, i = "") => e(n) && e(r) ? [.../* @__PURE__ */ new Set([...Object.keys(n), ...Object.keys(r)])].flatMap((e) => t(n[e], r[e], i ? `${i}.${e}` : e)) : JSON.stringify(n) === JSON.stringify(r) ? [] : [{
|
|
3
|
+
path: i,
|
|
4
|
+
...n === void 0 ? {} : { before: n },
|
|
5
|
+
...r === void 0 ? {} : { after: r }
|
|
6
|
+
}], n = (t) => e(t) ? t : {}, r = (e) => {
|
|
7
|
+
let t = n(e).definition?.type;
|
|
8
|
+
return t ? t === "layoutContainer" ? "layout" : t.replace(/([a-z])([A-Z])/gu, "$1 $2").toLowerCase() : "element";
|
|
9
|
+
}, i = (e) => n(e).definition?.parentId ?? void 0, a = (e, t) => {
|
|
10
|
+
let n = t.get(e);
|
|
11
|
+
return n === void 0 ? `“${e}”` : `${r(n)} “${e}”`;
|
|
12
|
+
}, o = (e) => {
|
|
13
|
+
let t = e.split("."), n = t[0], r = t.length > 1 ? t[1] : n;
|
|
14
|
+
if (n === "attributes") return r;
|
|
15
|
+
let i = {
|
|
16
|
+
label: "label",
|
|
17
|
+
styleSelectors: "classes",
|
|
18
|
+
bindings: "bindings",
|
|
19
|
+
interactions: "interactions",
|
|
20
|
+
initialState: "initial state",
|
|
21
|
+
items: void 0,
|
|
22
|
+
parentId: void 0,
|
|
23
|
+
rootId: void 0,
|
|
24
|
+
type: "type"
|
|
25
|
+
};
|
|
26
|
+
return Object.hasOwn(i, r) ? i[r] : r;
|
|
27
|
+
}, s = (e, t = 3) => e.length > t ? `${e.slice(0, t).join(", ")} and ${e.length - t} more` : e.join(", "), c = {
|
|
28
|
+
folder: "folder",
|
|
29
|
+
variable: "variable",
|
|
30
|
+
setting: "setting",
|
|
31
|
+
selector: "class",
|
|
32
|
+
globalStyle: "global style for",
|
|
33
|
+
idStyle: "id style",
|
|
34
|
+
token: "token",
|
|
35
|
+
font: "font",
|
|
36
|
+
file: "function file"
|
|
37
|
+
}, l = {
|
|
38
|
+
add: "Added",
|
|
39
|
+
update: "Changed",
|
|
40
|
+
remove: "Removed"
|
|
41
|
+
}, u = (t, n) => {
|
|
42
|
+
let r = e(t) ? t : {}, i = e(n) ? n : {};
|
|
43
|
+
return [.../* @__PURE__ */ new Set([...Object.keys(r), ...Object.keys(i)])].filter((e) => JSON.stringify(r[e]) !== JSON.stringify(i[e]));
|
|
44
|
+
}, d = (e) => e.kind !== "element", f = (e) => {
|
|
45
|
+
let { kind: t } = e;
|
|
46
|
+
if (t === "setting" && e.id === "pages") return {
|
|
47
|
+
text: "Reordered the pages",
|
|
48
|
+
action: "reorder"
|
|
49
|
+
};
|
|
50
|
+
let n = `${l[e.op]} ${c[t]} “${e.id}”`;
|
|
51
|
+
if (e.op === "update" && (t === "selector" || t === "globalStyle" || t === "idStyle")) {
|
|
52
|
+
let t = u(e.before, e.after);
|
|
53
|
+
return {
|
|
54
|
+
text: t.length > 0 ? `${n} on ${t.join(", ")}` : n,
|
|
55
|
+
action: e.op
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
text: n,
|
|
60
|
+
action: e.op
|
|
61
|
+
};
|
|
62
|
+
}, p = (e) => {
|
|
63
|
+
let t = /* @__PURE__ */ new Set();
|
|
64
|
+
return e.filter((e) => !t.has(e.text) && (t.add(e.text), !0));
|
|
65
|
+
}, m = (e) => {
|
|
66
|
+
let r = e.filter((e) => e.kind === "element"), c = new Map(r.map((e) => [e.id, e.after ?? e.before])), l = new Set(r.filter((e) => e.op !== "update" || i(e.before) !== i(e.after)).map((e) => e.id)), u = [];
|
|
67
|
+
for (let e of r) {
|
|
68
|
+
let r = a(e.id, c), d = (t, n) => u.push({
|
|
69
|
+
text: t,
|
|
70
|
+
action: n,
|
|
71
|
+
elementId: e.id
|
|
72
|
+
});
|
|
73
|
+
if (e.op === "add") {
|
|
74
|
+
let t = i(e.after);
|
|
75
|
+
d(t ? `Added ${r} to ${a(t, c)}` : `Added ${r}`, "add");
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (e.op === "remove") {
|
|
79
|
+
let t = i(e.before);
|
|
80
|
+
d(t ? `Removed ${r} from ${a(t, c)}` : `Removed ${r}`, "remove");
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
let f = i(e.before), p = i(e.after);
|
|
84
|
+
f !== p && f && p && d(`Moved ${r} from ${a(f, c)} to ${a(p, c)}`, "move");
|
|
85
|
+
let m = t(e.before, e.after), h = [...new Set(m.map((e) => o(e.path)).filter((e) => e !== void 0))];
|
|
86
|
+
h.length > 0 && d(`Changed ${s(h)} of ${r}`, "update");
|
|
87
|
+
let g = (e) => (n(e).definition?.items ?? []).filter((e) => !l.has(e)), _ = m.some((e) => e.path === "definition.items");
|
|
88
|
+
_ && JSON.stringify(g(e.before)) !== JSON.stringify(g(e.after)) && d(`Reordered the children of ${r}`, "reorder"), (m.length === 0 || h.length === 0 && !_ && f === p) && d(`Changed ${r}`, "update");
|
|
89
|
+
}
|
|
90
|
+
return u.push(...e.filter(d).map(f)), p(u);
|
|
91
|
+
};
|
|
92
|
+
//#endregion
|
|
93
|
+
export { m as describeChange, t as fieldChanges, p as uniqueLines };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ChangeEntry } from './types';
|
|
2
|
+
import { Schema, Style } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Structural equality for documents as they are stored: JSON — objects, arrays and scalars, nothing else.
|
|
5
|
+
*
|
|
6
|
+
* Written out rather than borrowed because it runs on every save of a space, over every element of it, and almost
|
|
7
|
+
* every pair it compares is equal: what it has to be is a walk that stops at the first difference, with nothing to
|
|
8
|
+
* set up per call.
|
|
9
|
+
*/
|
|
10
|
+
export declare const sameValue: (a: unknown, b: unknown) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A copy of a stored document, for the model that has to remember what it last saved.
|
|
13
|
+
*
|
|
14
|
+
* JSON rather than a structural clone: documents are JSON by definition, and the round trip measures about half of
|
|
15
|
+
* `cloneDeep` on a 5 000-element schema — a cost every save of a space pays.
|
|
16
|
+
*/
|
|
17
|
+
export declare const jsonCopy: <T>(value: T) => T;
|
|
18
|
+
/** The part of a schema a history reads: what is stored, never what the runtime derives from it. */
|
|
19
|
+
export type HistorySchema = Pick<Schema, 'flat' | 'pages' | 'pageFolders' | 'variables' | 'settings' | 'definition'>;
|
|
20
|
+
/**
|
|
21
|
+
* What changed between two versions of a schema, entity by entity.
|
|
22
|
+
*
|
|
23
|
+
* An element is one entity: whatever changed inside it — an attribute, a binding, a flow, its place in the tree —
|
|
24
|
+
* the entry carries it whole, before and after. Pages are elements; their ORDER is the setting `pages`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const diffSchema: (before: Partial<HistorySchema>, after: Partial<HistorySchema>) => ChangeEntry[];
|
|
27
|
+
/** The part of a style a history reads. Its `cache` is not: it is the whole stylesheet, compiled from the rest. */
|
|
28
|
+
export type HistoryStyle = Pick<Style, 'platform' | 'variables' | 'fonts' | 'theme' | 'mode'>;
|
|
29
|
+
/**
|
|
30
|
+
* What changed between two versions of a style. A selector is one entity across the display modes, so "tablet only"
|
|
31
|
+
* reads as one change to it, with the modes compared inside the entry.
|
|
32
|
+
*/
|
|
33
|
+
export declare const diffStyle: (before: Partial<HistoryStyle>, after: Partial<HistoryStyle>) => ChangeEntry[];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//#region src/history/diff.ts
|
|
2
|
+
var e = (t, n) => {
|
|
3
|
+
if (t === n) return !0;
|
|
4
|
+
if (typeof t != "object" || typeof n != "object" || t === null || n === null || Array.isArray(t) !== Array.isArray(n)) return !1;
|
|
5
|
+
if (Array.isArray(t) && Array.isArray(n)) return t.length === n.length && t.every((t, r) => e(t, n[r]));
|
|
6
|
+
let r = t, i = n, a = Object.keys(r).filter((e) => r[e] !== void 0);
|
|
7
|
+
return a.length === Object.keys(i).filter((e) => i[e] !== void 0).length && a.every((t) => Object.hasOwn(i, t) && e(r[t], i[t]));
|
|
8
|
+
}, t = (e) => JSON.parse(JSON.stringify(e)), n = (t, n, r) => {
|
|
9
|
+
let i = [];
|
|
10
|
+
for (let [a, o] of Object.entries(r)) Object.hasOwn(n, a) ? e(n[a], o) || i.push({
|
|
11
|
+
kind: t,
|
|
12
|
+
id: a,
|
|
13
|
+
op: "update",
|
|
14
|
+
before: n[a],
|
|
15
|
+
after: o
|
|
16
|
+
}) : i.push({
|
|
17
|
+
kind: t,
|
|
18
|
+
id: a,
|
|
19
|
+
op: "add",
|
|
20
|
+
after: o
|
|
21
|
+
});
|
|
22
|
+
for (let [e, a] of Object.entries(n)) Object.hasOwn(r, e) || i.push({
|
|
23
|
+
kind: t,
|
|
24
|
+
id: e,
|
|
25
|
+
op: "remove",
|
|
26
|
+
before: a
|
|
27
|
+
});
|
|
28
|
+
return i;
|
|
29
|
+
}, r = (e, t) => Object.fromEntries((e ?? []).map((e) => [t(e), e])), i = (e, t) => Object.fromEntries(Object.entries(t ?? {}).map(([t, n]) => [`${e}.${t}`, n])), a = (e, t) => [
|
|
30
|
+
...n("element", e.flat ?? {}, t.flat ?? {}),
|
|
31
|
+
...n("folder", r(e.pageFolders, (e) => e.id), r(t.pageFolders, (e) => e.id)),
|
|
32
|
+
...n("variable", r(e.variables, (e) => e.name), r(t.variables, (e) => e.name)),
|
|
33
|
+
...n("setting", {
|
|
34
|
+
...i("settings", e.settings),
|
|
35
|
+
...i("definition", e.definition),
|
|
36
|
+
pages: e.pages
|
|
37
|
+
}, {
|
|
38
|
+
...i("settings", t.settings),
|
|
39
|
+
...i("definition", t.definition),
|
|
40
|
+
pages: t.pages
|
|
41
|
+
})
|
|
42
|
+
], o = {
|
|
43
|
+
class: "selector",
|
|
44
|
+
element: "globalStyle",
|
|
45
|
+
id: "idStyle"
|
|
46
|
+
}, s = (e) => {
|
|
47
|
+
let t = {};
|
|
48
|
+
for (let [n, r] of Object.entries(e ?? {})) for (let [e, i] of Object.entries(r)) {
|
|
49
|
+
let r = o[i.type], a = t[r] ??= {};
|
|
50
|
+
(a[e] ??= {})[n] = i;
|
|
51
|
+
}
|
|
52
|
+
return t;
|
|
53
|
+
}, c = (e) => Object.fromEntries(Object.entries(e ?? {}).flatMap(([e, t]) => Object.entries(t).map(([t, n]) => [`${e}/${t}`, n]))), l = (e, t) => {
|
|
54
|
+
let i = s(e.platform), a = s(t.platform);
|
|
55
|
+
return [
|
|
56
|
+
...[
|
|
57
|
+
"selector",
|
|
58
|
+
"globalStyle",
|
|
59
|
+
"idStyle"
|
|
60
|
+
].flatMap((e) => n(e, i[e] ?? {}, a[e] ?? {})),
|
|
61
|
+
...n("token", c(e.variables), c(t.variables)),
|
|
62
|
+
...n("font", r(e.fonts, (e) => e.family), r(t.fonts, (e) => e.family)),
|
|
63
|
+
...n("setting", {
|
|
64
|
+
theme: e.theme,
|
|
65
|
+
mode: e.mode
|
|
66
|
+
}, {
|
|
67
|
+
theme: t.theme,
|
|
68
|
+
mode: t.mode
|
|
69
|
+
})
|
|
70
|
+
];
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { a as diffSchema, l as diffStyle, t as jsonCopy, e as sameValue };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { describeChange as e, fieldChanges as t, uniqueLines as n } from "./describe.mjs";
|
|
2
|
+
import { diffSchema as r, diffStyle as i, jsonCopy as a, sameValue as o } from "./diff.mjs";
|
|
3
|
+
export { e as describeChange, r as diffSchema, i as diffStyle, t as fieldChanges, a as jsonCopy, o as sameValue, n as uniqueLines };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Which of a space's documents a change was made to: its schema, its style, or its functions' source. */
|
|
2
|
+
export type ChangeDocument = 'schema' | 'style' | 'functions';
|
|
3
|
+
/**
|
|
4
|
+
* Where a change came from: a person in the builder, an agent over MCP, the builder's co-worker, the autofix, a GraphQL
|
|
5
|
+
* client that is not a person, or a writer with nothing to say (a seed, a script).
|
|
6
|
+
*/
|
|
7
|
+
export type ChangeOrigin = 'builder' | 'mcp' | 'coworker' | 'autofix' | 'api' | 'system';
|
|
8
|
+
/**
|
|
9
|
+
* What one entry is about. Schema: an element (pages and layouts are elements too), a page folder, a schema variable,
|
|
10
|
+
* a setting (`settings.<key>`, `definition.<key>`, the page order `pages`). Style: a class selector, a global style
|
|
11
|
+
* (a bare element selector), an id style, a design token (`<category>/<name>`), a font family, a style setting
|
|
12
|
+
* (`theme`, `mode`). Functions: a file of their source, by its path (`index.ts`, `lib/feed.ts`).
|
|
13
|
+
*/
|
|
14
|
+
export type ChangeKind = 'element' | 'folder' | 'variable' | 'setting' | 'selector' | 'globalStyle' | 'idStyle' | 'token' | 'font' | 'file';
|
|
15
|
+
/** One entity that changed, whole, before and after: the field-level difference is derived from the two. */
|
|
16
|
+
export type ChangeEntry = {
|
|
17
|
+
kind: ChangeKind;
|
|
18
|
+
id: string;
|
|
19
|
+
op: 'add' | 'remove' | 'update';
|
|
20
|
+
/** Absent on `add`. */
|
|
21
|
+
before?: unknown;
|
|
22
|
+
/** Absent on `remove`. */
|
|
23
|
+
after?: unknown;
|
|
24
|
+
};
|
|
25
|
+
export type ChangeAuthor = {
|
|
26
|
+
userId: number | null;
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
/** One save that changed something: who, from where, and every entity it touched. */
|
|
30
|
+
export type SpaceChange = {
|
|
31
|
+
spaceId: number;
|
|
32
|
+
environment: string;
|
|
33
|
+
/** Monotonic per space and environment: the timeline's order and the address of a point in it. */
|
|
34
|
+
seq: number;
|
|
35
|
+
/** Milliseconds. */
|
|
36
|
+
at: number;
|
|
37
|
+
document: ChangeDocument;
|
|
38
|
+
author: ChangeAuthor;
|
|
39
|
+
origin: ChangeOrigin;
|
|
40
|
+
/** The MCP client's name, or the builder tab's instance id. */
|
|
41
|
+
client?: string;
|
|
42
|
+
/** Everything one request wrote shares it: one builder request, one `plitzi_apply`, one autofix. */
|
|
43
|
+
batch: string;
|
|
44
|
+
entries: ChangeEntry[];
|
|
45
|
+
summary: string;
|
|
46
|
+
/** The entries name what changed but carry no values: the whole change was too large to store as one record. */
|
|
47
|
+
truncated?: boolean;
|
|
48
|
+
};
|
|
File without changes
|
package/dist/index.d.ts
CHANGED