@plitzi/sdk-shared 0.37.9 → 0.37.10

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 (130) hide show
  1. package/CHANGELOG.md +585 -0
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.mjs +3 -3
  4. package/dist/actions/triggerParams.mjs +7 -6
  5. package/dist/actions/validateDocument.d.ts +3 -0
  6. package/dist/actions/validateDocument.mjs +89 -88
  7. package/dist/authoring/elementCallbacks.d.ts +65 -0
  8. package/dist/authoring/elementCallbacks.mjs +72 -8
  9. package/dist/authoring/index.mjs +3 -3
  10. package/dist/builder/contexts/BuilderContext.d.ts +18 -7
  11. package/dist/connectors/index.d.ts +1 -1
  12. package/dist/connectors/index.mjs +2 -2
  13. package/dist/connectors/validateManifest.d.ts +3 -0
  14. package/dist/connectors/validateManifest.mjs +77 -76
  15. package/dist/dataSource/computed.mjs +25 -29
  16. package/dist/dataSource/globalSources.d.ts +15 -0
  17. package/dist/dataSource/globalSources.mjs +13 -0
  18. package/dist/dataSource/index.d.ts +2 -0
  19. package/dist/dataSource/index.mjs +8 -7
  20. package/dist/devTools/utils/PlitziConsole.d.ts +9 -0
  21. package/dist/devTools/utils/PlitziConsole.mjs +27 -7
  22. package/dist/flags/flagsCookie.d.ts +26 -0
  23. package/dist/flags/flagsCookie.mjs +20 -0
  24. package/dist/flags/index.d.ts +3 -0
  25. package/dist/flags/index.mjs +4 -0
  26. package/dist/flags/resolveFlags.d.ts +60 -0
  27. package/dist/flags/resolveFlags.mjs +38 -0
  28. package/dist/flags/schemaFlag.d.ts +11 -0
  29. package/dist/flags/schemaFlag.mjs +9 -0
  30. package/dist/flags/useFlagResolution.d.ts +13 -0
  31. package/dist/flags/useFlagResolution.mjs +43 -0
  32. package/dist/helpers/eventTarget.d.ts +10 -0
  33. package/dist/helpers/eventTarget.mjs +4 -0
  34. package/dist/helpers/images.d.ts +18 -0
  35. package/dist/helpers/images.mjs +13 -0
  36. package/dist/helpers/index.d.ts +3 -0
  37. package/dist/helpers/index.mjs +21 -18
  38. package/dist/helpers/interval.d.ts +18 -0
  39. package/dist/helpers/interval.mjs +7 -0
  40. package/dist/helpers/isRecord.d.ts +2 -0
  41. package/dist/helpers/isRecord.mjs +4 -0
  42. package/dist/helpers/scroll.d.ts +42 -0
  43. package/dist/helpers/scroll.mjs +30 -0
  44. package/dist/helpers/twigWrapper/TemplateCache/TemplateCache.mjs +1 -1
  45. package/dist/helpers/twigWrapper/filters/filters.mjs +38 -2
  46. package/dist/history/describe.mjs +3 -1
  47. package/dist/history/diff.d.ts +1 -1
  48. package/dist/history/diff.mjs +1 -0
  49. package/dist/history/types.d.ts +1 -1
  50. package/dist/hooks/index.mjs +5 -5
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.mjs +90 -76
  53. package/dist/navigation/routes.mjs +6 -4
  54. package/dist/network/graphql/builder/Mutations/Space/SpaceAddSnippetMutation.d.ts +2 -0
  55. package/dist/network/graphql/builder/Mutations/Space/SpaceAddSnippetMutation.mjs +4 -0
  56. package/dist/network/graphql/builder/Mutations/Space/flags/SpacePublishFlagsMutation.d.ts +12 -0
  57. package/dist/network/graphql/builder/Mutations/Space/flags/SpacePublishFlagsMutation.mjs +4 -0
  58. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceRemoveFlagMutation.d.ts +2 -0
  59. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceRemoveFlagMutation.mjs +4 -0
  60. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceSetFlagMutation.d.ts +3 -0
  61. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceSetFlagMutation.mjs +4 -0
  62. package/dist/network/graphql/builder/Mutations/index.d.ts +5 -1
  63. package/dist/network/graphql/builder/Mutations/index.mjs +122 -116
  64. package/dist/network/graphql/builder/Queries/InitQuery.d.ts +3 -1
  65. package/dist/network/graphql/builder/Queries/InitQuery.mjs +1 -1
  66. package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.d.ts +16 -2
  67. package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.mjs +1 -1
  68. package/dist/network/graphql/builder/Queries/index.d.ts +1 -1
  69. package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +1 -1
  70. package/dist/network/graphql/sdk/Queries/InitQuery.mjs +1 -1
  71. package/dist/network/index.mjs +8 -7
  72. package/dist/network/spaceEvents.d.ts +12 -6
  73. package/dist/network/spaceEvents.mjs +153 -154
  74. package/dist/realtime/client.mjs +123 -95
  75. package/dist/realtime/topics.mjs +18 -17
  76. package/dist/schema/anchor.d.ts +8 -0
  77. package/dist/schema/anchor.mjs +4 -0
  78. package/dist/schema/index.d.ts +2 -0
  79. package/dist/schema/index.mjs +6 -4
  80. package/dist/schema/serverElements.d.ts +6 -2
  81. package/dist/schema/serverElements.mjs +17 -16
  82. package/dist/schema/snippet.d.ts +7 -0
  83. package/dist/schema/snippet.mjs +9 -0
  84. package/dist/schema/wire.d.ts +11 -0
  85. package/dist/schema/wire.mjs +27 -0
  86. package/dist/server/actions/useImagesSync.d.ts +9 -0
  87. package/dist/server/actions/useImagesSync.mjs +7 -0
  88. package/dist/server/rsc/refreshRsc.mjs +8 -8
  89. package/dist/source/snapshot.mjs +23 -22
  90. package/dist/state/paintedState.mjs +13 -12
  91. package/dist/state/runtimeStatePersist.mjs +50 -49
  92. package/dist/store/index.d.ts +45 -45
  93. package/dist/style/breakpoints.d.ts +11 -0
  94. package/dist/style/breakpoints.mjs +8 -0
  95. package/dist/style/displayModes.d.ts +5 -0
  96. package/dist/style/displayModes.mjs +8 -0
  97. package/dist/style/fontValidation.mjs +52 -51
  98. package/dist/style/fonts.d.ts +0 -12
  99. package/dist/style/fonts.mjs +11 -11
  100. package/dist/style/index.d.ts +4 -0
  101. package/dist/style/index.mjs +11 -7
  102. package/dist/style/layoutGrid.d.ts +30 -0
  103. package/dist/style/layoutGrid.mjs +33 -0
  104. package/dist/style/notifications.d.ts +52 -0
  105. package/dist/style/notifications.mjs +55 -0
  106. package/dist/style/snippetStyle.d.ts +23 -0
  107. package/dist/style/snippetStyle.mjs +32 -0
  108. package/dist/style/styleConstants.d.ts +7 -2
  109. package/dist/style/styleConstants.mjs +10 -0
  110. package/dist/style/styleStates.d.ts +11 -2
  111. package/dist/style/styleStates.mjs +12 -9
  112. package/dist/theme/ThemeProvider.mjs +20 -20
  113. package/dist/types/CommonTypes.d.ts +3 -0
  114. package/dist/types/DevToolsTypes.d.ts +29 -4
  115. package/dist/types/EventBridgeTypes.d.ts +2 -2
  116. package/dist/types/PluginTypes.d.ts +1 -1
  117. package/dist/types/ResourceTypes.d.ts +2 -2
  118. package/dist/types/SchemaTypes.d.ts +62 -3
  119. package/dist/types/ServerTypes.d.ts +47 -0
  120. package/dist/types/SnippetTypes.d.ts +28 -0
  121. package/dist/types/StoreTypes.d.ts +25 -0
  122. package/dist/types/StyleTypes.d.ts +1 -1
  123. package/dist/types/index.d.ts +1 -1
  124. package/package.json +104 -8
  125. package/tailwind.config.js +1 -6
  126. package/vite.config.ts +16 -4
  127. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.d.ts +0 -2
  128. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.mjs +0 -4
  129. package/dist/types/TemplateTypes.d.ts +0 -20
  130. /package/dist/types/{TemplateTypes.mjs → SnippetTypes.mjs} +0 -0
@@ -0,0 +1,11 @@
1
+ import { DisplayMode } from '../types';
2
+ /**
3
+ * Where each display mode begins, in CSS pixels — the widths a style's breakpoints are compiled at (`sdk-style`'s
4
+ * `generateCache`). A desktop's rules are the base; a tablet's apply up to and including 1024px and a phone's up to
5
+ * and including 768px, the phone's winning where the two meet.
6
+ */
7
+ export declare const DISPLAY_MODE_MIN_WIDTH: Record<DisplayMode, number>;
8
+ /** The same width as a media query writes it: in rem at the browser's default 16px, so it follows a visitor's zoom. */
9
+ export declare const displayModeWidthRem: (mode: DisplayMode) => string;
10
+ /** The display mode whose rules a page shows at a viewport width. */
11
+ export declare const displayModeAt: (width: number) => DisplayMode;
@@ -0,0 +1,8 @@
1
+ //#region src/style/breakpoints.ts
2
+ var e = {
3
+ desktop: 1024,
4
+ tablet: 768,
5
+ mobile: 0
6
+ }, t = (t) => e[t] === 0 ? "0" : `${String(e[t] / 16)}rem`, n = (t) => t <= e.tablet ? "mobile" : t <= e.desktop ? "tablet" : "desktop";
7
+ //#endregion
8
+ export { e as DISPLAY_MODE_MIN_WIDTH, n as displayModeAt, t as displayModeWidthRem };
@@ -0,0 +1,5 @@
1
+ import { DisplayMode } from '../types';
2
+ /** The breakpoints a style is written for, widest first — the keys of `Style['platform']`. */
3
+ export declare const DISPLAY_MODES: readonly ["desktop", "tablet", "mobile"];
4
+ /** Whether a key read off a document — `Object.keys(platform)` — is one of them. */
5
+ export declare const isDisplayMode: (value: string) => value is DisplayMode;
@@ -0,0 +1,8 @@
1
+ //#region src/style/displayModes.ts
2
+ var e = [
3
+ "desktop",
4
+ "tablet",
5
+ "mobile"
6
+ ], t = (t) => e.some((e) => e === t);
7
+ //#endregion
8
+ export { e as DISPLAY_MODES, t as isDisplayMode };
@@ -1,107 +1,108 @@
1
- import { isSafeFontUrl as e } from "./fonts.mjs";
1
+ import { isRecord as e } from "../helpers/isRecord.mjs";
2
+ import { isSafeFontUrl as t } from "./fonts.mjs";
2
3
  //#region src/style/fontValidation.ts
3
- var t = /* @__PURE__ */ new Set([
4
+ var n = /* @__PURE__ */ new Set([
4
5
  "system",
5
6
  "google",
6
7
  "remote",
7
8
  "hosted"
8
- ]), n = /* @__PURE__ */ new Set([
9
+ ]), r = /* @__PURE__ */ new Set([
9
10
  "auto",
10
11
  "block",
11
12
  "swap",
12
13
  "fallback",
13
14
  "optional"
14
- ]), r = /* @__PURE__ */ new Set(["woff2", "woff"]), i = 100, a = (e) => {
15
+ ]), i = /* @__PURE__ */ new Set(["woff2", "woff"]), a = 100, o = (e) => {
15
16
  for (let t = 0; t < e.length; t += 1) {
16
17
  let n = e.charCodeAt(t);
17
18
  if (n < 32 || n === 127) return !0;
18
19
  }
19
20
  return !1;
20
- }, o = class extends Error {}, s = (e) => {
21
- throw new o(e);
22
- }, c = (e) => typeof e == "object" && !!e && !Array.isArray(e), l = (e) => {
23
- if (typeof e != "string") return s("font.family must be a string");
21
+ }, s = class extends Error {}, c = (e) => {
22
+ throw new s(e);
23
+ }, l = (e) => {
24
+ if (typeof e != "string") return c("font.family must be a string");
24
25
  let t = e.trim();
25
- return t ? t.length > i ? s(`font.family cannot be longer than ${i} characters`) : a(t) ? s("font.family cannot contain control characters") : t : s("font.family cannot be empty");
26
+ return t ? t.length > a ? c(`font.family cannot be longer than ${a} characters`) : o(t) ? c("font.family cannot contain control characters") : t : c("font.family cannot be empty");
26
27
  }, u = (e) => {
27
28
  if (e === void 0) return [400];
28
- if (!Array.isArray(e) || e.length === 0) return s("font.weights must be a non-empty list of numbers");
29
- let t = e.map((e) => typeof e != "number" || !Number.isInteger(e) || e < 1 || e > 1e3 ? s("font.weights must hold whole numbers between 1 and 1000") : e);
29
+ if (!Array.isArray(e) || e.length === 0) return c("font.weights must be a non-empty list of numbers");
30
+ let t = e.map((e) => typeof e != "number" || !Number.isInteger(e) || e < 1 || e > 1e3 ? c("font.weights must hold whole numbers between 1 and 1000") : e);
30
31
  return [...new Set(t)].sort((e, t) => e - t);
31
32
  }, d = (e) => {
32
33
  if (e === void 0) return ["normal"];
33
- if (!Array.isArray(e) || e.length === 0) return s("font.styles must be a non-empty list");
34
- let t = e.map((e) => e !== "normal" && e !== "italic" ? s("font.styles may only hold \"normal\" or \"italic\"") : e);
34
+ if (!Array.isArray(e) || e.length === 0) return c("font.styles must be a non-empty list");
35
+ let t = e.map((e) => e !== "normal" && e !== "italic" ? c("font.styles may only hold \"normal\" or \"italic\"") : e);
35
36
  return [...new Set(t)];
36
- }, f = (e, t) => {
37
- if (!c(e)) return s(`font.files[${t}] must be an object`);
38
- let { weight: n, style: i, format: a, unicodeRange: o } = e;
39
- if (typeof n != "number" || !Number.isInteger(n) || n < 1 || n > 1e3) return s(`font.files[${t}].weight must be a whole number between 1 and 1000`);
40
- if (i !== "normal" && i !== "italic") return s(`font.files[${t}].style must be "normal" or "italic"`);
41
- if (typeof a != "string" || !r.has(a)) return s(`font.files[${t}].format must be "woff2" or "woff"`);
37
+ }, f = (t, n) => {
38
+ if (!e(t)) return c(`font.files[${n}] must be an object`);
39
+ let { weight: r, style: a, format: o, unicodeRange: s } = t;
40
+ if (typeof r != "number" || !Number.isInteger(r) || r < 1 || r > 1e3) return c(`font.files[${n}].weight must be a whole number between 1 and 1000`);
41
+ if (a !== "normal" && a !== "italic") return c(`font.files[${n}].style must be "normal" or "italic"`);
42
+ if (typeof o != "string" || !i.has(o)) return c(`font.files[${n}].format must be "woff2" or "woff"`);
42
43
  let l = {
43
- weight: n,
44
- style: i,
45
- format: a
44
+ weight: r,
45
+ style: a,
46
+ format: o
46
47
  };
47
- if (o !== void 0) {
48
- if (typeof o != "string") return s(`font.files[${t}].unicodeRange must be a string`);
49
- l.unicodeRange = o;
48
+ if (s !== void 0) {
49
+ if (typeof s != "string") return c(`font.files[${n}].unicodeRange must be a string`);
50
+ l.unicodeRange = s;
50
51
  }
51
52
  return l;
52
- }, p = (e, t) => typeof e != "string" || !e ? s(`font.files[${t}].path must be a non-empty string`) : e.includes("://") || e.startsWith("/") ? s(`font.files[${t}].path must be relative to the font store, not a URL`) : e.split("/").includes("..") ? s(`font.files[${t}].path cannot climb out of the font store`) : e, m = (e) => !Array.isArray(e) || e.length === 0 ? s("font.files must be a non-empty list") : e, h = (r) => {
53
- if (!c(r)) return s("a font must be an object");
54
- let { source: i, fallback: a, display: o, preload: h } = r;
55
- if (typeof i != "string" || !t.has(i)) return s("font.source must be one of: system, google, remote, hosted");
56
- if (typeof a != "string" || !a.trim()) return s("font.fallback is required: it is what renders until the face arrives");
57
- if (o !== void 0 && (typeof o != "string" || !n.has(o))) return s("font.display must be one of: auto, block, swap, fallback, optional");
58
- if (h !== void 0 && typeof h != "boolean") return s("font.preload must be a boolean");
53
+ }, p = (e, t) => typeof e != "string" || !e ? c(`font.files[${t}].path must be a non-empty string`) : e.includes("://") || e.startsWith("/") ? c(`font.files[${t}].path must be relative to the font store, not a URL`) : e.split("/").includes("..") ? c(`font.files[${t}].path cannot climb out of the font store`) : e, m = (e) => !Array.isArray(e) || e.length === 0 ? c("font.files must be a non-empty list") : e, h = (i) => {
54
+ if (!e(i)) return c("a font must be an object");
55
+ let { source: a, fallback: o, display: s, preload: h } = i;
56
+ if (typeof a != "string" || !n.has(a)) return c("font.source must be one of: system, google, remote, hosted");
57
+ if (typeof o != "string" || !o.trim()) return c("font.fallback is required: it is what renders until the face arrives");
58
+ if (s !== void 0 && (typeof s != "string" || !r.has(s))) return c("font.display must be one of: auto, block, swap, fallback, optional");
59
+ if (h !== void 0 && typeof h != "boolean") return c("font.preload must be a boolean");
59
60
  let g = {
60
- family: l(r.family),
61
- fallback: a.trim(),
62
- weights: u(r.weights),
63
- styles: d(r.styles),
64
- ...o === void 0 ? {} : { display: o },
61
+ family: l(i.family),
62
+ fallback: o.trim(),
63
+ weights: u(i.weights),
64
+ styles: d(i.styles),
65
+ ...s === void 0 ? {} : { display: s },
65
66
  ...h === void 0 ? {} : { preload: h }
66
67
  };
67
- if (i === "system") return {
68
+ if (a === "system") return {
68
69
  ...g,
69
70
  source: "system"
70
71
  };
71
- if (i === "google") {
72
- let { subsets: e } = r;
73
- return e !== void 0 && (!Array.isArray(e) || e.some((e) => typeof e != "string")) ? s("font.subsets must be a list of strings") : {
72
+ if (a === "google") {
73
+ let { subsets: e } = i;
74
+ return e !== void 0 && (!Array.isArray(e) || e.some((e) => typeof e != "string")) ? c("font.subsets must be a list of strings") : {
74
75
  ...g,
75
76
  source: "google",
76
77
  ...e === void 0 ? {} : { subsets: e }
77
78
  };
78
79
  }
79
- if (i === "remote") {
80
- let { stylesheet: t, files: n } = r;
81
- return t === void 0 && n === void 0 ? s("a remote font needs either a stylesheet URL or the font files themselves") : t === void 0 ? {
80
+ if (a === "remote") {
81
+ let { stylesheet: e, files: n } = i;
82
+ return e === void 0 && n === void 0 ? c("a remote font needs either a stylesheet URL or the font files themselves") : e === void 0 ? {
82
83
  ...g,
83
84
  source: "remote",
84
- files: m(n).map((t, n) => {
85
- let r = f(t, n), { url: i } = t;
86
- return typeof i != "string" || !e(i) ? s(`font.files[${n}].url must be an https URL with no credentials in it`) : {
85
+ files: m(n).map((e, n) => {
86
+ let r = f(e, n), { url: i } = e;
87
+ return typeof i != "string" || !t(i) ? c(`font.files[${n}].url must be an https URL with no credentials in it`) : {
87
88
  ...r,
88
89
  url: i
89
90
  };
90
91
  })
91
- } : typeof t != "string" || !e(t) ? s("font.stylesheet must be an https URL with no credentials in it") : {
92
+ } : typeof e != "string" || !t(e) ? c("font.stylesheet must be an https URL with no credentials in it") : {
92
93
  ...g,
93
94
  source: "remote",
94
- stylesheet: t
95
+ stylesheet: e
95
96
  };
96
97
  }
97
98
  return {
98
99
  ...g,
99
100
  source: "hosted",
100
- files: m(r.files).map((e, t) => ({
101
+ files: m(i.files).map((e, t) => ({
101
102
  ...f(e, t),
102
103
  path: p(e.path, t)
103
104
  }))
104
105
  };
105
106
  };
106
107
  //#endregion
107
- export { o as FontValidationError, h as parseSpaceFont };
108
+ export { s as FontValidationError, h as parseSpaceFont };
@@ -23,18 +23,6 @@ export declare const fontFamilyStack: (font: SpaceFont) => string;
23
23
  /** The family a `font-family` value leads with — the one the manifest is keyed by. The rest of the value is the
24
24
  * fallback chain, which names nothing this space has to load. */
25
25
  export declare const primaryFamily: (value: string) => string;
26
- /**
27
- * One `css2` request for every Google family in the manifest.
28
- *
29
- * The axis tuples have to be listed in ascending order or the API answers 400, and the families
30
- * are sorted for a reason of our own: the URL is a cache key, and two spaces with the same fonts
31
- * in a different order should not be two entries in every CDN between here and the visitor.
32
- *
33
- * `subsets` is deliberately NOT sent. The v1 API took `subset=`; css2 answers with the full set of
34
- * unicode-range-split faces and lets the browser fetch only the ranges a page actually uses, which
35
- * is strictly better. The field stays on the manifest because mirroring (which downloads files
36
- * rather than linking them) does have to know which ranges to keep.
37
- */
38
26
  export declare const googleCss2Url: (fonts: GoogleFont[]) => string;
39
27
  /**
40
28
  * The stylesheet that draws family NAMES in their own typeface — the font picker, and nothing else.
@@ -84,15 +84,15 @@ var e = "https://fonts.googleapis.com", t = {
84
84
  }, d = (e) => (e.split(",")[0] ?? "").trim().replace(/^['"]|['"]$/g, "").trim(), f = (e) => {
85
85
  let t = [...new Set(e.weights)].filter((e) => Number.isFinite(e)).sort((e, t) => e - t);
86
86
  return t.length > 0 ? t : [400];
87
- }, p = (e) => encodeURIComponent(e).replace(/%20/g, "+"), m = (t) => {
88
- let n = [...t].sort((e, t) => e.family.localeCompare(t.family)).map((e) => {
87
+ }, p = (e) => encodeURIComponent(e).replace(/%20/g, "+"), m = (e, t) => e === t ? 0 : e < t ? -1 : 1, h = (t) => {
88
+ let n = [...t].sort((e, t) => m(e.family, t.family)).map((e) => {
89
89
  let t = f(e);
90
90
  if (!e.styles.includes("italic")) return `family=${p(e.family)}:wght@${t.join(";")}`;
91
91
  let n = [0, 1].flatMap((e) => t.map((t) => `${e},${t}`));
92
92
  return `family=${p(e.family)}:ital,wght@${n.join(";")}`;
93
93
  }), r = [...new Set(t.map((e) => e.display ?? "swap"))], i = r.length === 1 ? r[0] : "swap";
94
94
  return `${e}/css2?${n.join("&")}&display=${i}`;
95
- }, h = (t, n) => `${e}/css2?${[...t].sort((e, t) => e.localeCompare(t)).map((e) => `family=${p(e)}`).join("&")}&text=${encodeURIComponent(n)}&display=swap`, g = "/fonts", _ = (e = g) => (t) => `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}`, v = /* @__PURE__ */ new Set([
95
+ }, g = (t, n) => `${e}/css2?${[...t].sort(m).map((e) => `family=${p(e)}`).join("&")}&text=${encodeURIComponent(n)}&display=swap`, _ = "/fonts", v = (e = _) => (t) => `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}`, y = /* @__PURE__ */ new Set([
96
96
  "serif",
97
97
  "sans-serif",
98
98
  "monospace",
@@ -111,16 +111,16 @@ var e = "https://fonts.googleapis.com", t = {
111
111
  "revert",
112
112
  "revert-layer",
113
113
  "unset"
114
- ]), y = (e) => {
114
+ ]), b = (e) => {
115
115
  let t = /* @__PURE__ */ new Set();
116
116
  for (let n of e.matchAll(/font-family\s*:\s*([^;}]+)/g)) {
117
117
  let e = n[1];
118
118
  if (e.includes("var(")) continue;
119
119
  let r = d(e);
120
- r && !v.has(r.toLowerCase()) && t.add(r);
120
+ r && !y.has(r.toLowerCase()) && t.add(r);
121
121
  }
122
122
  return [...t];
123
- }, b = (e, t) => [
123
+ }, x = (e, t) => [
124
124
  "@font-face{",
125
125
  `font-family:${s(e.family)};`,
126
126
  `font-style:${t.style === "italic" ? "italic" : "normal"};`,
@@ -129,12 +129,12 @@ var e = "https://fonts.googleapis.com", t = {
129
129
  `src:url(${s(t.url)}) format(${s(t.format)});`,
130
130
  t.unicodeRange && c.test(t.unicodeRange) ? `unicode-range:${t.unicodeRange};` : "",
131
131
  "}"
132
- ].join(""), x = (n, r) => {
132
+ ].join(""), S = (n, r) => {
133
133
  let o = [], s = [], c = [], l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Set(), d = (e, t) => {
134
134
  e && (u.add(e), l.set(e, (l.get(e) ?? !1) || t));
135
135
  }, f = n.filter((e) => e.source === "google");
136
136
  if (f.length > 0) {
137
- let t = m(f);
137
+ let t = h(f);
138
138
  d(e, !1), d("https://fonts.gstatic.com", !0), f.some((e) => e.preload) && s.push({
139
139
  href: t,
140
140
  rel: "preload",
@@ -158,7 +158,7 @@ var e = "https://fonts.googleapis.com", t = {
158
158
  }
159
159
  if (e.source === "remote" && e.files) {
160
160
  e.files.filter((e) => i(e.url)).forEach((n) => {
161
- d(a(n.url), !0), c.push(b(e, {
161
+ d(a(n.url), !0), c.push(x(e, {
162
162
  ...n,
163
163
  url: n.url
164
164
  })), e.preload && s.push({
@@ -173,7 +173,7 @@ var e = "https://fonts.googleapis.com", t = {
173
173
  }
174
174
  e.source === "hosted" && e.files.forEach((n) => {
175
175
  let i = r(n.path);
176
- d(a(i), !0), c.push(b(e, {
176
+ d(a(i), !0), c.push(x(e, {
177
177
  ...n,
178
178
  url: i
179
179
  })), e.preload && s.push({
@@ -195,4 +195,4 @@ var e = "https://fonts.googleapis.com", t = {
195
195
  };
196
196
  };
197
197
  //#endregion
198
- export { n as SYSTEM_FONTS, r as availableFonts, y as familiesInCss, u as fontFamilyStack, _ as fontUrlResolver, x as fontsToHead, m as googleCss2Url, h as googleTextSubsetUrl, i as isSafeFontUrl, d as primaryFamily };
198
+ export { n as SYSTEM_FONTS, r as availableFonts, b as familiesInCss, u as fontFamilyStack, v as fontUrlResolver, S as fontsToHead, h as googleCss2Url, g as googleTextSubsetUrl, i as isSafeFontUrl, d as primaryFamily };
@@ -1,9 +1,13 @@
1
1
  import { default as styleConstants } from './styleConstants';
2
+ export * from './breakpoints';
3
+ export * from './displayModes';
2
4
  export * from './fontAssets';
3
5
  export * from './fontValidation';
4
6
  export * from './fonts';
5
7
  export * from './fontsFromCss';
8
+ export * from './layoutGrid';
6
9
  export * from './runtimeStyle';
10
+ export * from './snippetStyle';
7
11
  export * from './styleConstants';
8
12
  export * from './styleStates';
9
13
  export { styleConstants };
@@ -1,8 +1,12 @@
1
1
  import e, { EMPTY_STYLE_SCHEMA as t, StyleBindingsAllowed as n, baseDefaultValue as r, inheritableAttributesBase as i } from "./styleConstants.mjs";
2
- import { fontLinkAssets as a } from "./fontAssets.mjs";
3
- import { SYSTEM_FONTS as o, availableFonts as s, familiesInCss as c, fontFamilyStack as l, fontUrlResolver as u, fontsToHead as d, googleCss2Url as f, googleTextSubsetUrl as p, isSafeFontUrl as m, primaryFamily as h } from "./fonts.mjs";
4
- import { FontValidationError as g, parseSpaceFont as _ } from "./fontValidation.mjs";
5
- import { fallbackForFamily as v, fontsFromCss as y } from "./fontsFromCss.mjs";
6
- import { RUNTIME_STYLE_ID as b, markStyleCache as x, styleCacheFromDocument as S, styleCacheTravelsInDocument as C } from "./runtimeStyle.mjs";
7
- import { HIDDEN_CLASS as w, STYLE_STATES as T, STYLE_STATE_LABELS as E, inCascadeOrder as D, isKnownState as O, isStartingState as k, stateSuffix as A } from "./styleStates.mjs";
8
- export { t as EMPTY_STYLE_SCHEMA, g as FontValidationError, w as HIDDEN_CLASS, b as RUNTIME_STYLE_ID, T as STYLE_STATES, E as STYLE_STATE_LABELS, o as SYSTEM_FONTS, n as StyleBindingsAllowed, s as availableFonts, r as baseDefaultValue, v as fallbackForFamily, c as familiesInCss, l as fontFamilyStack, a as fontLinkAssets, u as fontUrlResolver, y as fontsFromCss, d as fontsToHead, f as googleCss2Url, p as googleTextSubsetUrl, D as inCascadeOrder, i as inheritableAttributesBase, O as isKnownState, m as isSafeFontUrl, k as isStartingState, x as markStyleCache, _ as parseSpaceFont, h as primaryFamily, A as stateSuffix, S as styleCacheFromDocument, C as styleCacheTravelsInDocument, e as styleConstants };
2
+ import { DISPLAY_MODE_MIN_WIDTH as a, displayModeAt as o, displayModeWidthRem as s } from "./breakpoints.mjs";
3
+ import { DISPLAY_MODES as c, isDisplayMode as l } from "./displayModes.mjs";
4
+ import { fontLinkAssets as u } from "./fontAssets.mjs";
5
+ import { SYSTEM_FONTS as d, availableFonts as f, familiesInCss as p, fontFamilyStack as m, fontUrlResolver as h, fontsToHead as g, googleCss2Url as _, googleTextSubsetUrl as v, isSafeFontUrl as y, primaryFamily as b } from "./fonts.mjs";
6
+ import { FontValidationError as x, parseSpaceFont as S } from "./fontValidation.mjs";
7
+ import { fallbackForFamily as C, fontsFromCss as w } from "./fontsFromCss.mjs";
8
+ import { LAYOUT_GRIDS as T, layoutGridCss as E, layoutGridLook as D } from "./layoutGrid.mjs";
9
+ import { RUNTIME_STYLE_ID as O, markStyleCache as k, styleCacheFromDocument as A, styleCacheTravelsInDocument as j } from "./runtimeStyle.mjs";
10
+ import { mergeSnippetStyle as M, sameSelector as N, selectorsOf as P } from "./snippetStyle.mjs";
11
+ import { CURRENT_PAGE_SELECTOR as F, HIDDEN_CLASS as I, STYLE_STATES as L, STYLE_STATE_LABELS as R, inCascadeOrder as z, isKnownState as B, isStartingState as V, stateSuffix as H } from "./styleStates.mjs";
12
+ export { F as CURRENT_PAGE_SELECTOR, c as DISPLAY_MODES, a as DISPLAY_MODE_MIN_WIDTH, t as EMPTY_STYLE_SCHEMA, x as FontValidationError, I as HIDDEN_CLASS, T as LAYOUT_GRIDS, O as RUNTIME_STYLE_ID, L as STYLE_STATES, R as STYLE_STATE_LABELS, d as SYSTEM_FONTS, n as StyleBindingsAllowed, f as availableFonts, r as baseDefaultValue, o as displayModeAt, s as displayModeWidthRem, C as fallbackForFamily, p as familiesInCss, m as fontFamilyStack, u as fontLinkAssets, h as fontUrlResolver, w as fontsFromCss, g as fontsToHead, _ as googleCss2Url, v as googleTextSubsetUrl, z as inCascadeOrder, i as inheritableAttributesBase, l as isDisplayMode, B as isKnownState, y as isSafeFontUrl, V as isStartingState, E as layoutGridCss, D as layoutGridLook, k as markStyleCache, M as mergeSnippetStyle, S as parseSpaceFont, b as primaryFamily, N as sameSelector, P as selectorsOf, H as stateSuffix, A as styleCacheFromDocument, j as styleCacheTravelsInDocument, e as styleConstants };
@@ -0,0 +1,30 @@
1
+ import { DisplayMode } from '../types';
2
+ /**
3
+ * The layout grid drawn over a page on request: the columns it is usually laid out on — twelve on a desktop, eight on
4
+ * a tablet, four on a phone — so an element can be lined up by eye with the rest of it. The builder draws it over its
5
+ * canvas, the dev tools over a running page; both read it from here.
6
+ */
7
+ export interface LayoutGrid {
8
+ columns: number;
9
+ gutter: number;
10
+ /** Clear on each side of the columns. */
11
+ margin: number;
12
+ /** The widest the columns get together; the margins grow past it. */
13
+ maxWidth?: number;
14
+ }
15
+ export declare const LAYOUT_GRIDS: Record<DisplayMode, LayoutGrid>;
16
+ export interface LayoutGridLook {
17
+ width: string;
18
+ backgroundImage: string;
19
+ boxShadow: string;
20
+ }
21
+ /**
22
+ * How a grid is drawn on a box as wide as the page and centred in it: its width, its columns as a gradient, its edges.
23
+ * `zoom` scales every length, for a page drawn zoomed by an element the grid's box is not inside.
24
+ */
25
+ export declare const layoutGridLook: ({ columns, gutter, margin, maxWidth }: LayoutGrid, zoom?: number) => LayoutGridLook;
26
+ /**
27
+ * The grid as rules for a document of its own — the builder's canvas frame: fixed to its viewport and through to the
28
+ * page, the tablet's and the phone's taking over at the widths the page's own breakpoints switch at.
29
+ */
30
+ export declare const layoutGridCss: (zoom?: number) => string;
@@ -0,0 +1,33 @@
1
+ import { displayModeWidthRem as e } from "./breakpoints.mjs";
2
+ //#region src/style/layoutGrid.ts
3
+ var t = {
4
+ desktop: {
5
+ columns: 12,
6
+ gutter: 24,
7
+ margin: 32,
8
+ maxWidth: 1200
9
+ },
10
+ tablet: {
11
+ columns: 8,
12
+ gutter: 20,
13
+ margin: 24
14
+ },
15
+ mobile: {
16
+ columns: 4,
17
+ gutter: 16,
18
+ margin: 16
19
+ }
20
+ }, n = "rgba(91, 61, 245, 0.07)", r = "rgba(91, 61, 245, 0.32)", i = (e, t) => `${String(e * t)}px`, a = ({ columns: e, gutter: t, margin: a, maxWidth: o }, s = 1) => {
21
+ let c = `calc(100% - ${i(a * 2, s)})`, l = `calc((100% - ${i(t * (e - 1), s)}) / ${String(e)})`;
22
+ return {
23
+ width: o === void 0 ? c : `min(${i(o, s)}, ${c})`,
24
+ backgroundImage: `repeating-linear-gradient(to right, ${n} 0px, ${n} ${l}, transparent ${l}, transparent calc(${l} + ${i(t, s)}))`,
25
+ boxShadow: `inset 1px 0 ${r}, inset -1px 0 ${r}`
26
+ };
27
+ }, o = (e) => `width: ${e.width}; background-image: ${e.backgroundImage};`, s = (n = 1) => [
28
+ `html::after { content: ''; position: fixed; top: 0; bottom: 0; left: 50%; z-index: 2147483000; transform: translateX(-50%); pointer-events: none; box-shadow: ${a(t.desktop, n).boxShadow}; ${o(a(t.desktop, n))} }`,
29
+ `@media (max-width: ${e("desktop")}) { html::after { ${o(a(t.tablet, n))} } }`,
30
+ `@media (max-width: ${e("tablet")}) { html::after { ${o(a(t.mobile, n))} } }`
31
+ ].join("\n");
32
+ //#endregion
33
+ export { t as LAYOUT_GRIDS, s as layoutGridCss, a as layoutGridLook };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * How a space's notifications look — the toasts an `addNotification` step shows.
3
+ *
4
+ * Every value is any CSS colour or length, and a token is the right answer for all of them (`'var(--card)'`): a token
5
+ * follows the light/dark toggle, which the notifications already do. Left out, a value keeps the library's own.
6
+ */
7
+ export interface NotificationsSpec {
8
+ /** The toast's surface. */
9
+ background?: string;
10
+ /** Its text. */
11
+ text?: string;
12
+ /** The accent of each `appearance`: its icon and its progress bar. */
13
+ success?: string;
14
+ danger?: string;
15
+ warning?: string;
16
+ info?: string;
17
+ /** Corner radius, e.g. `'12px'`. */
18
+ radius?: string;
19
+ /** Its typeface — the space's own, as a token: `'var(--font-sans)'`. */
20
+ font?: string;
21
+ /** Its text size, e.g. `'13px'`. */
22
+ fontSize?: string;
23
+ /** Its edge, as `border` writes it: `'1px solid var(--border)'`. */
24
+ border?: string;
25
+ /** Its depth, as `box-shadow` writes it: `'var(--shadow-lg)'`. */
26
+ shadow?: string;
27
+ /** The room inside it, e.g. `'12px 14px'`. */
28
+ padding?: string;
29
+ }
30
+ /** Every field `notifications` takes — what an editor of the setting (the MCP server's `patchSettings`) offers. */
31
+ export declare const NOTIFICATIONS_FIELDS: readonly (keyof NotificationsSpec)[];
32
+ /** Why a notifications spec would not style anything — a field it does not take, a value that is not one CSS value —
33
+ * or `undefined` when it is sound. A `;` or a brace in a value would end the declaration early and let the rest of
34
+ * the text become rules of its own. */
35
+ export declare const notificationsProblem: (spec: Record<string, unknown> | undefined) => string | undefined;
36
+ /**
37
+ * The rule that styles the toast container, or `''` when there is nothing to say. Fields it does not take and empty
38
+ * values say nothing; {@link notificationsProblem} is the check for a spec someone wrote.
39
+ */
40
+ export declare const notificationsCss: (spec: NotificationsSpec | undefined) => string;
41
+ /** The space's custom CSS with its notifications' rule after it — how a space's `customCss` carries both. */
42
+ export declare const withNotificationsCss: (customCss: string, spec: NotificationsSpec | undefined) => string;
43
+ /**
44
+ * A space's custom CSS read apart: the notifications' rule {@link notificationsCss} wrote, back as the spec, and the
45
+ * space's own CSS without it — so an editor shows and changes each on its own, and writes them together again with
46
+ * {@link withNotificationsCss}. A rule someone edited into something else (a declaration that is no field's) is left
47
+ * where it is, as the space's own CSS: read back, it would lose what was added to it.
48
+ */
49
+ export declare const splitNotificationsCss: (customCss: string) => {
50
+ notifications: NotificationsSpec;
51
+ customCss: string;
52
+ };
@@ -0,0 +1,55 @@
1
+ //#region src/style/notifications.ts
2
+ var e = {
3
+ background: ["--toastify-color-light", "--toastify-color-dark"],
4
+ text: ["--toastify-text-color-light", "--toastify-text-color-dark"],
5
+ success: ["--toastify-color-success"],
6
+ danger: ["--toastify-color-error"],
7
+ warning: ["--toastify-color-warning"],
8
+ info: ["--toastify-color-info"],
9
+ radius: ["--toastify-toast-bd-radius"],
10
+ font: ["--toastify-font-family"],
11
+ shadow: ["--toastify-toast-shadow"],
12
+ padding: ["--toastify-toast-padding"]
13
+ }, t = {
14
+ fontSize: "font-size",
15
+ border: "border"
16
+ }, n = [...Object.keys(e), ...Object.keys(t)], r = (e) => n.includes(e), i = n.filter(r), a = ".Toastify__toast-container.plitzi-sdk-toasts", o = (e) => {
17
+ for (let [t, i] of Object.entries(e ?? {})) {
18
+ if (!r(t)) return `\`notifications\` has no "${t}". It takes ${n.join(", ")}.`;
19
+ if (i !== void 0 && (typeof i != "string" || i.trim() === "" || /[;{}]/.test(i))) return `\`notifications.${t}\` is ${JSON.stringify(i)}, which is not one CSS value. Write a colour or a length, like 'var(--card)' or '12px'.`;
20
+ }
21
+ }, s = (n) => {
22
+ let i = [], o = [];
23
+ for (let [a, s] of Object.entries(n ?? {})) {
24
+ if (!r(a) || typeof s != "string" || s.trim() === "") continue;
25
+ let n = t[a];
26
+ n ? o.push(` ${n}: ${s.trim()};`) : i.push(...(e[a] ?? []).map((e) => ` ${e}: ${s.trim()};`));
27
+ }
28
+ return [i.length > 0 ? `${a} {\n${i.join("\n")}\n}` : "", o.length > 0 ? `:where(${a} .Toastify__toast) {\n${o.join("\n")}\n}` : ""].filter(Boolean).join("\n");
29
+ }, c = (e, t) => [e, s(t)].filter(Boolean).join("\n\n"), l = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), u = RegExp(`${l(a)}\\s*\\{([^}]*)\\}`), d = RegExp(`:where\\(${l(a)} \\.Toastify__toast\\)\\s*\\{([^}]*)\\}`), f = (e, t) => {
30
+ let n = [];
31
+ for (let r of e.split(";").map((e) => e.trim()).filter(Boolean)) {
32
+ let e = r.indexOf(":"), i = e > 0 ? t(r.slice(0, e).trim()) : void 0;
33
+ if (!i) return;
34
+ n.push([i, r.slice(e + 1).trim()]);
35
+ }
36
+ return n;
37
+ }, p = new Map(Object.entries(e).flatMap(([e, t]) => r(e) ? t.map((t) => [t, e]) : [])), m = new Map(Object.entries(t).flatMap(([e, t]) => r(e) ? [[t, e]] : [])), h = (e) => {
38
+ let t = {};
39
+ for (let [n, r] of [[u, (e) => p.get(e)], [d, (e) => m.get(e)]]) {
40
+ let i = n.exec(e);
41
+ for (let [e, n] of (i ? f(i[1], r) : void 0) ?? []) t[e] = n;
42
+ }
43
+ let n = Object.keys(t).length > 0 ? s(t) : "";
44
+ if (!n || !e.endsWith(n)) return {
45
+ notifications: {},
46
+ customCss: e
47
+ };
48
+ let r = e.slice(0, e.length - n.length);
49
+ return {
50
+ notifications: t,
51
+ customCss: r.endsWith("\n\n") ? r.slice(0, -2) : r
52
+ };
53
+ };
54
+ //#endregion
55
+ export { i as NOTIFICATIONS_FIELDS, s as notificationsCss, o as notificationsProblem, h as splitNotificationsCss, c as withNotificationsCss };
@@ -0,0 +1,23 @@
1
+ import { SnippetStyle, Style, StyleVariables } from '../types';
2
+ /** Every selector a style answers to, in any display mode. */
3
+ export declare const selectorsOf: (platform: Partial<Style["platform"]>) => Set<string>;
4
+ /**
5
+ * Whether a selector says the same in two styles: the same rules in every display mode, and in the same modes. A
6
+ * selector one of them does not hold at all is not the same.
7
+ */
8
+ export declare const sameSelector: (name: string, left: Partial<Style["platform"]>, right: Partial<Style["platform"]>) => boolean;
9
+ /**
10
+ * A snippet's style, added to the style of the space it lands in — and nothing of the space's changed by it.
11
+ *
12
+ * A rule is added where the space has none under that name, in that display mode; a token where the space has none
13
+ * of that name. What the space already holds stays as it is: a class every element of the space wears, or a colour
14
+ * the whole space reads, is not the snippet's to restyle. A snippet whose class says something else under a name the
15
+ * space uses has been renamed before it gets here (`fitSnippet`, `@plitzi/sdk-schema`), so the only names left in
16
+ * common are the ones that say the same.
17
+ *
18
+ * The one rule both the editor and the server merge by, so the style a drop leaves is the same on both.
19
+ */
20
+ export declare const mergeSnippetStyle: (space: SnippetStyle, snippet: SnippetStyle) => {
21
+ platform: Style["platform"];
22
+ variables: Partial<StyleVariables>;
23
+ };
@@ -0,0 +1,32 @@
1
+ import { sameValue as e } from "../history/diff.mjs";
2
+ import { StyleVariableCategory as t } from "../types/StyleTypes.mjs";
3
+ import { isDisplayMode as n } from "./displayModes.mjs";
4
+ //#region src/style/snippetStyle.ts
5
+ var r = (...e) => [...new Set(e.flatMap((e) => Object.keys(e).filter(n)))], i = (e) => {
6
+ if (!e) return;
7
+ let { cache: t, ...n } = e;
8
+ return n;
9
+ }, a = (e) => new Set(Object.values(e).flatMap((e) => Object.keys(e))), o = (t, n, a) => r(n, a).every((r) => e(i(n[r]?.[t]), i(a[r]?.[t]))), s = (e, n) => {
10
+ let i = { ...e.platform };
11
+ r(n.platform).forEach((t) => {
12
+ let r = Object.entries(n.platform[t]).filter(([n]) => !Object.hasOwn(e.platform[t], n));
13
+ i[t] = {
14
+ ...e.platform[t],
15
+ ...Object.fromEntries(r)
16
+ };
17
+ });
18
+ let a = { ...e.variables };
19
+ for (let e of Object.values(t)) {
20
+ let t = n.variables?.[e], r = a[e] ?? {}, i = Object.entries(t ?? {}).filter(([e]) => !Object.hasOwn(r, e));
21
+ i.length > 0 && (a[e] = {
22
+ ...r,
23
+ ...Object.fromEntries(i)
24
+ });
25
+ }
26
+ return {
27
+ platform: i,
28
+ variables: a
29
+ };
30
+ };
31
+ //#endregion
32
+ export { s as mergeSnippetStyle, o as sameSelector, a as selectorsOf };