@pixerate/editor 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +71 -1
  2. package/THIRD_PARTY_NOTICES.md +29 -0
  3. package/dist/agent/index.cjs +10 -9
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +1 -1
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +4 -3
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +3173 -340
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +617 -4
  12. package/dist/canvas/index.d.ts +617 -4
  13. package/dist/canvas/index.js +3105 -272
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  16. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  17. package/dist/{chunk-XNORY7M6.cjs → chunk-7WISYZFO.cjs} +105 -50
  18. package/dist/chunk-7WISYZFO.cjs.map +1 -0
  19. package/dist/{chunk-OLZJXL4R.cjs → chunk-AL6JMGWW.cjs} +59 -25
  20. package/dist/chunk-AL6JMGWW.cjs.map +1 -0
  21. package/dist/chunk-BVP3TSLH.cjs +69 -0
  22. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  23. package/dist/{chunk-MCSJFWAO.cjs → chunk-C7P22VIP.cjs} +670 -96
  24. package/dist/chunk-C7P22VIP.cjs.map +1 -0
  25. package/dist/{chunk-PGNZKFQS.js → chunk-ECCCYKGL.js} +76 -21
  26. package/dist/chunk-ECCCYKGL.js.map +1 -0
  27. package/dist/{chunk-3CN2WD3X.js → chunk-FH6F67DN.js} +646 -72
  28. package/dist/chunk-FH6F67DN.js.map +1 -0
  29. package/dist/chunk-HRMEDT2L.js +1406 -0
  30. package/dist/chunk-HRMEDT2L.js.map +1 -0
  31. package/dist/{chunk-ITBSKI26.js → chunk-IXHSYOVY.js} +941 -9
  32. package/dist/chunk-IXHSYOVY.js.map +1 -0
  33. package/dist/{chunk-FODNLX5N.js → chunk-NAXVVS5I.js} +38 -4
  34. package/dist/chunk-NAXVVS5I.js.map +1 -0
  35. package/dist/chunk-O5RYH2PG.js +69 -0
  36. package/dist/chunk-O5RYH2PG.js.map +1 -0
  37. package/dist/{chunk-SBCZ6RN5.cjs → chunk-PO6A6QQH.cjs} +1039 -107
  38. package/dist/chunk-PO6A6QQH.cjs.map +1 -0
  39. package/dist/{chunk-3LV6RRPH.js → chunk-QGYDWPRM.js} +2 -2
  40. package/dist/{chunk-U5KWZU4X.js → chunk-RR7F5GUM.js} +2632 -129
  41. package/dist/chunk-RR7F5GUM.js.map +1 -0
  42. package/dist/{chunk-5S3Z4PPF.js → chunk-UAKDG62Z.js} +232 -25
  43. package/dist/chunk-UAKDG62Z.js.map +1 -0
  44. package/dist/{chunk-SML64VJG.cjs → chunk-V3CHHWOE.cjs} +4 -4
  45. package/dist/{chunk-SML64VJG.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
  46. package/dist/chunk-WSQKHXW7.cjs +5726 -0
  47. package/dist/chunk-WSQKHXW7.cjs.map +1 -0
  48. package/dist/{chunk-D27YFC46.cjs → chunk-X4N4WUKB.cjs} +267 -60
  49. package/dist/chunk-X4N4WUKB.cjs.map +1 -0
  50. package/dist/commands/index.cjs +74 -1
  51. package/dist/commands/index.cjs.map +1 -1
  52. package/dist/commands/index.d.cts +34 -1
  53. package/dist/commands/index.d.ts +34 -1
  54. package/dist/commands/index.js +73 -0
  55. package/dist/commands/index.js.map +1 -1
  56. package/dist/compare/index.cjs +3 -3
  57. package/dist/compare/index.d.cts +1 -1
  58. package/dist/compare/index.d.ts +1 -1
  59. package/dist/compare/index.js +2 -2
  60. package/dist/controller-BIJiNoVs.d.cts +1842 -0
  61. package/dist/controller-BIJiNoVs.d.ts +1842 -0
  62. package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
  63. package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
  64. package/dist/extensions/index.cjs +53 -6
  65. package/dist/extensions/index.cjs.map +1 -1
  66. package/dist/extensions/index.d.cts +12 -4
  67. package/dist/extensions/index.d.ts +12 -4
  68. package/dist/extensions/index.js +53 -6
  69. package/dist/generation/index.cjs +1013 -69
  70. package/dist/generation/index.cjs.map +1 -1
  71. package/dist/generation/index.d.cts +474 -13
  72. package/dist/generation/index.d.ts +474 -13
  73. package/dist/generation/index.js +976 -32
  74. package/dist/generation/index.js.map +1 -1
  75. package/dist/image-editor/index.cjs +3385 -1275
  76. package/dist/image-editor/index.cjs.map +1 -1
  77. package/dist/image-editor/index.d.cts +693 -128
  78. package/dist/image-editor/index.d.ts +693 -128
  79. package/dist/image-editor/index.js +3325 -1215
  80. package/dist/image-editor/index.js.map +1 -1
  81. package/dist/{index-fJrlkJCd.d.ts → index-7a6bHTLy.d.ts} +494 -5
  82. package/dist/{index-BhJBSm2d.d.cts → index-Csd5qI8u.d.cts} +494 -5
  83. package/dist/index.cjs +1491 -45
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +110 -19
  86. package/dist/index.d.ts +110 -19
  87. package/dist/index.js +1464 -18
  88. package/dist/index.js.map +1 -1
  89. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  90. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  91. package/dist/model-C1zApQM8.d.cts +219 -0
  92. package/dist/model-C1zApQM8.d.ts +219 -0
  93. package/dist/persistence/index.d.cts +3 -120
  94. package/dist/persistence/index.d.ts +3 -120
  95. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
  96. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
  97. package/dist/serializers/index.cjs +12 -4
  98. package/dist/serializers/index.cjs.map +1 -1
  99. package/dist/serializers/index.d.cts +39 -12
  100. package/dist/serializers/index.d.ts +39 -12
  101. package/dist/serializers/index.js +12 -4
  102. package/dist/spreadsheet/index.cjs +127 -3
  103. package/dist/spreadsheet/index.cjs.map +1 -1
  104. package/dist/spreadsheet/index.d.cts +431 -11
  105. package/dist/spreadsheet/index.d.ts +431 -11
  106. package/dist/spreadsheet/index.js +127 -3
  107. package/dist/storage-BpFfspHm.d.cts +120 -0
  108. package/dist/storage-BpFfspHm.d.ts +120 -0
  109. package/dist/tokens/index.cjs +115 -0
  110. package/dist/tokens/index.cjs.map +1 -0
  111. package/dist/tokens/index.d.cts +212 -0
  112. package/dist/tokens/index.d.ts +212 -0
  113. package/dist/tokens/index.js +115 -0
  114. package/dist/tokens/index.js.map +1 -0
  115. package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
  116. package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
  117. package/package.json +6 -1
  118. package/dist/chunk-3CN2WD3X.js.map +0 -1
  119. package/dist/chunk-5S3Z4PPF.js.map +0 -1
  120. package/dist/chunk-D27YFC46.cjs.map +0 -1
  121. package/dist/chunk-FODNLX5N.js.map +0 -1
  122. package/dist/chunk-ITBSKI26.js.map +0 -1
  123. package/dist/chunk-MA2F5KHF.cjs +0 -3223
  124. package/dist/chunk-MA2F5KHF.cjs.map +0 -1
  125. package/dist/chunk-MCSJFWAO.cjs.map +0 -1
  126. package/dist/chunk-OLZJXL4R.cjs.map +0 -1
  127. package/dist/chunk-PGNZKFQS.js.map +0 -1
  128. package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
  129. package/dist/chunk-U5KWZU4X.js.map +0 -1
  130. package/dist/chunk-XNORY7M6.cjs.map +0 -1
  131. package/dist/controller-BhLLAoi8.d.cts +0 -1000
  132. package/dist/controller-BhLLAoi8.d.ts +0 -1000
  133. /package/dist/{chunk-3LV6RRPH.js.map → chunk-QGYDWPRM.js.map} +0 -0
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Design tokens (Figma-style "variables"): collections hold modes (e.g. Light / Dark) and
3
+ * typed variables with one value per mode. A value is a literal or an alias to another
4
+ * variable of the same type, possibly in another collection.
5
+ *
6
+ * The state is plain, immutable, JSON-serialisable data. Every operation returns a new state.
7
+ */
8
+ /** A variable's type. */
9
+ type TokenType = 'color' | 'number' | 'string' | 'boolean';
10
+ declare const TOKEN_TYPES: readonly TokenType[];
11
+ /** A resolved value: colours are normalised hex strings (`#rrggbb` or `#rrggbbaa`). */
12
+ type TokenLiteral = string | number | boolean;
13
+ /** A reference to another variable (by id). */
14
+ interface TokenAlias {
15
+ alias: string;
16
+ }
17
+ /** What a variable holds in one mode. */
18
+ type TokenValue = TokenLiteral | TokenAlias;
19
+ interface TokenMode {
20
+ id: string;
21
+ name: string;
22
+ }
23
+ interface TokenCollection {
24
+ id: string;
25
+ name: string;
26
+ /** At least one mode. The first one is the default mode. */
27
+ modes: readonly TokenMode[];
28
+ }
29
+ /**
30
+ * Which properties pickers offer a variable for (figcraft / Figma scope ids). Scopes only
31
+ * filter pickers: binding out of scope still works.
32
+ */
33
+ type TokenScope = 'ALL_SCOPES' | 'ALL_FILLS' | 'FRAME_FILL' | 'SHAPE_FILL' | 'TEXT_FILL' | 'STROKE_COLOR' | 'EFFECT_COLOR' | 'CORNER_RADIUS' | 'WIDTH_HEIGHT' | 'GAP' | 'OPACITY' | 'STROKE_FLOAT' | 'EFFECT_FLOAT' | 'FONT_WEIGHT' | 'FONT_SIZE' | 'LINE_HEIGHT' | 'LETTER_SPACING' | 'PARAGRAPH_SPACING' | 'PARAGRAPH_INDENT' | 'TEXT_CONTENT' | 'FONT_FAMILY' | 'FONT_STYLE';
34
+ interface TokenVariable {
35
+ id: string;
36
+ /** Unique within its collection. `/` separates groups (`color/bg`). */
37
+ name: string;
38
+ collectionId: string;
39
+ type: TokenType;
40
+ /** Value per mode id of the collection. */
41
+ valuesByMode: Readonly<Record<string, TokenValue>>;
42
+ description?: string;
43
+ /** Pickers offer the variable for these scopes; `undefined` = every supported property. */
44
+ scopes?: readonly TokenScope[];
45
+ /** Unit for number variables in CSS / W3C export (`px`, `rem`, `ms`, …). */
46
+ unit?: string;
47
+ }
48
+ interface TokenState {
49
+ collections: readonly TokenCollection[];
50
+ variables: readonly TokenVariable[];
51
+ }
52
+ /**
53
+ * Chosen mode per collection: `{ [collectionId]: modeId }`. Collections not listed (or with an
54
+ * unknown mode) use their default (first) mode.
55
+ */
56
+ type TokenModeContext = Readonly<Record<string, string>>;
57
+ type TokenErrorCode = 'not-found' | 'invalid-name' | 'duplicate-name' | 'name-conflict' | 'invalid-type' | 'invalid-value' | 'type-mismatch' | 'alias-missing' | 'alias-cycle' | 'last-mode' | 'unknown-scope' | 'invalid-input';
58
+ /** Thrown by token operations that are refused; `code` says why. */
59
+ declare class TokenError extends Error {
60
+ readonly code: TokenErrorCode;
61
+ constructor(code: TokenErrorCode, message: string);
62
+ }
63
+ declare function isTokenAlias(value: unknown): value is TokenAlias;
64
+ declare const EMPTY_TOKEN_STATE: TokenState;
65
+
66
+ declare function getTokenCollection(state: TokenState, id: string): TokenCollection | undefined;
67
+ declare function getTokenVariable(state: TokenState, id: string): TokenVariable | undefined;
68
+ /** The collection with this name. */
69
+ declare function findTokenCollection(state: TokenState, name: string): TokenCollection | undefined;
70
+ /** The variable named `name` (in `collectionId` when given, else the first match). */
71
+ declare function findTokenVariable(state: TokenState, name: string, collectionId?: string): TokenVariable | undefined;
72
+ /** The variables of a collection, in order. */
73
+ declare function getCollectionVariables(state: TokenState, collectionId: string): TokenVariable[];
74
+ /** The collection's default (first) mode. */
75
+ declare function getDefaultMode(collection: TokenCollection): TokenMode;
76
+ /** The mode with id `key`, else the one named `key`. */
77
+ declare function findTokenMode(collection: TokenCollection, key: string): TokenMode | undefined;
78
+ /** The mode `collection` is in under `modes` (its chosen mode if valid, else the default). */
79
+ declare function getCurrentMode(collection: TokenCollection, modes: TokenModeContext | undefined): TokenMode;
80
+ /** A new variable's value per type: black, 0, empty, true (figcraft's pinned defaults). */
81
+ declare function defaultTokenValue(type: TokenType): TokenLiteral;
82
+ /** The literal as `type`, or `null` when it does not fit (colours are normalised). */
83
+ declare function coerceTokenLiteral(type: TokenType, value: unknown): TokenLiteral | null;
84
+ /** The type of a literal value (strings that are colours count as strings). */
85
+ declare function literalTokenType(value: TokenLiteral): TokenType;
86
+ /** A short text for a value: hex, number, string, boolean, or `→ name` for an alias. */
87
+ declare function formatTokenValue(state: TokenState, value: TokenValue | undefined): string;
88
+ type TokenResolutionErrorCode = 'missing' | 'cycle' | 'no-value' | 'type-mismatch';
89
+ type TokenResolution = {
90
+ ok: true;
91
+ value: TokenLiteral;
92
+ type: TokenType;
93
+ /** The variable whose literal was used (the end of the alias chain). */
94
+ variable: TokenVariable;
95
+ /** Mode of `variable`'s collection that supplied the value. */
96
+ modeId: string;
97
+ /** Variable ids visited, starting with the requested one. */
98
+ chain: string[];
99
+ } | {
100
+ ok: false;
101
+ code: TokenResolutionErrorCode;
102
+ message: string;
103
+ chain: string[];
104
+ };
105
+ /**
106
+ * Resolves variable `id` under `modes` (collection id → mode id; the default mode otherwise),
107
+ * following aliases. Each variable along the chain is read in its own collection's mode.
108
+ * Cycles, missing variables and type changes along the chain are reported, never thrown.
109
+ */
110
+ declare function resolveToken(state: TokenState, id: string, modes?: TokenModeContext): TokenResolution;
111
+ /** The resolved literal, or `undefined` when it does not resolve. */
112
+ declare function resolveTokenValue(state: TokenState, id: string, modes?: TokenModeContext): TokenLiteral | undefined;
113
+ /** The value of `variableId` in mode `modeId` of its own collection (other collections in their default mode). */
114
+ declare function resolveTokenInMode(state: TokenState, variableId: string, modeId: string): TokenLiteral | undefined;
115
+ /**
116
+ * Why `variable` cannot alias `targetId`, or `null` when it can: the target must exist, have
117
+ * the same type, and not lead back to `variable` through any alias in any mode.
118
+ */
119
+ declare function checkTokenAlias(state: TokenState, variable: Pick<TokenVariable, 'id' | 'type' | 'name'>, targetId: string): TokenError | null;
120
+ declare const TOKEN_SCOPES_BY_TYPE: Readonly<Record<TokenType, readonly TokenScope[]>>;
121
+ /** Whether `scope` is a scope a variable of `type` can be limited to. */
122
+ declare function isTokenScopeKnown(type: TokenType, scope: string): scope is TokenScope;
123
+ /**
124
+ * Canonical scope list: known ids only, no repeats, `undefined` (no limit) when every
125
+ * supported property is named. Unknown ids throw `unknown-scope`.
126
+ */
127
+ declare function normalizeTokenScopes(type: TokenType, scopes: readonly string[] | null | undefined): TokenScope[] | undefined;
128
+ /** Whether pickers offer `variable` for a property of `scope` (no scope: any). */
129
+ declare function isTokenInScope(variable: Pick<TokenVariable, 'scopes'>, scope: TokenScope | undefined): boolean;
130
+ /** Trims each `/`-separated group; throws `invalid-name` when empty or not exportable. */
131
+ declare function normalizeTokenName(name: unknown, what?: string): string;
132
+ type TokenIdFactory = (kind: 'collection' | 'mode' | 'variable') => string;
133
+ /** Default id factory: `crypto.randomUUID`, with a counter fallback. */
134
+ declare const defaultTokenId: TokenIdFactory;
135
+ interface CreateTokenCollectionInput {
136
+ name: string;
137
+ /** Mode names (default `['Default']`). */
138
+ modes?: readonly string[];
139
+ }
140
+ declare function createTokenCollection(state: TokenState, input: CreateTokenCollectionInput, createId?: TokenIdFactory): {
141
+ state: TokenState;
142
+ collection: TokenCollection;
143
+ };
144
+ declare function renameTokenCollection(state: TokenState, id: string, name: string): TokenState;
145
+ /**
146
+ * Deletes variables `ids`. Variables aliasing one of them take its values (per mode: the deleted
147
+ * variable resolved in that mode when it is in the same collection, else in its default mode).
148
+ */
149
+ declare function deleteTokenVariables(state: TokenState, ids: Iterable<string>): {
150
+ state: TokenState;
151
+ deleted: string[];
152
+ };
153
+ /** Deletes a collection and its variables (aliases into it are detached to their values). */
154
+ declare function deleteTokenCollection(state: TokenState, id: string): {
155
+ state: TokenState;
156
+ deleted: string[];
157
+ };
158
+ /**
159
+ * Adds a mode. Variables start with the values of mode `from` (default: the default mode).
160
+ */
161
+ declare function addTokenMode(state: TokenState, collectionId: string, name: string, options?: {
162
+ from?: string;
163
+ }, createId?: TokenIdFactory): {
164
+ state: TokenState;
165
+ mode: TokenMode;
166
+ };
167
+ declare function renameTokenMode(state: TokenState, collectionId: string, modeId: string, name: string): TokenState;
168
+ /** Removes a mode and its values; a collection keeps at least one mode. */
169
+ declare function removeTokenMode(state: TokenState, collectionId: string, modeId: string): TokenState;
170
+ /** Moves a mode to index `to` (clamped). Index 0 makes it the default mode. */
171
+ declare function moveTokenMode(state: TokenState, collectionId: string, modeId: string, to: number): TokenState;
172
+ interface CreateTokenVariableInput {
173
+ collectionId: string;
174
+ name: string;
175
+ type: TokenType;
176
+ /** Value for every mode (literal or `{ alias }`). Default: the type's default. */
177
+ value?: unknown;
178
+ /** Values by mode id or name (win over `value`). */
179
+ values?: Readonly<Record<string, unknown>>;
180
+ description?: string;
181
+ scopes?: readonly string[];
182
+ unit?: string;
183
+ }
184
+ /** A value for `variable`: a normalised literal or a checked alias. Throws when refused. */
185
+ declare function prepareTokenValue(state: TokenState, variable: Pick<TokenVariable, 'id' | 'type' | 'name'>, value: unknown): TokenValue;
186
+ declare function createTokenVariable(state: TokenState, input: CreateTokenVariableInput, createId?: TokenIdFactory): {
187
+ state: TokenState;
188
+ variable: TokenVariable;
189
+ };
190
+ /**
191
+ * Sets a variable's value in one mode (id or name; default: the default mode) to a literal or
192
+ * `{ alias: variableId }`. Aliases must keep the type and not create a cycle.
193
+ */
194
+ declare function setTokenValue(state: TokenState, variableId: string, value: unknown, modeId?: string): TokenState;
195
+ declare function renameTokenVariable(state: TokenState, variableId: string, name: string): TokenState;
196
+ interface UpdateTokenVariableInput {
197
+ description?: string;
198
+ /** `null` clears the limit (every property). */
199
+ scopes?: readonly string[] | null;
200
+ /** `null` clears the unit. */
201
+ unit?: string | null;
202
+ }
203
+ declare function updateTokenVariable(state: TokenState, variableId: string, input: UpdateTokenVariableInput): TokenState;
204
+ interface TokenStateIssue {
205
+ message: string;
206
+ collectionId?: string;
207
+ variableId?: string;
208
+ }
209
+ /**
210
+ * Reads untrusted data (e.g. a saved `TokenState`) and keeps what is valid: junk collections,
211
+ * modes and variables are dropped, bad values replaced by the type's default and alias cycles
212
+ * broken, each with an issue.
213
+ */
214
+ declare function parseTokenState(input: unknown): {
215
+ state: TokenState;
216
+ issues: TokenStateIssue[];
217
+ };
218
+
219
+ export { resolveToken as $, deleteTokenCollection as A, deleteTokenVariables as B, type CreateTokenVariableInput as C, findTokenCollection as D, EMPTY_TOKEN_STATE as E, findTokenMode as F, findTokenVariable as G, formatTokenValue as H, getCollectionVariables as I, getCurrentMode as J, getDefaultMode as K, getTokenCollection as L, getTokenVariable as M, isTokenAlias as N, isTokenInScope as O, isTokenScopeKnown as P, literalTokenType as Q, moveTokenMode as R, normalizeTokenName as S, type TokenState as T, type UpdateTokenVariableInput as U, normalizeTokenScopes as V, prepareTokenValue as W, removeTokenMode as X, renameTokenCollection as Y, renameTokenMode as Z, renameTokenVariable as _, type TokenIdFactory as a, resolveTokenInMode as a0, resolveTokenValue as a1, setTokenValue as a2, updateTokenVariable as a3, type TokenCollection as b, type TokenVariable as c, type TokenModeContext as d, type TokenResolution as e, type TokenLiteral as f, type TokenMode as g, type CreateTokenCollectionInput as h, TOKEN_SCOPES_BY_TYPE as i, TOKEN_TYPES as j, type TokenAlias as k, TokenError as l, type TokenErrorCode as m, type TokenResolutionErrorCode as n, type TokenScope as o, parseTokenState as p, type TokenStateIssue as q, type TokenType as r, type TokenValue as s, addTokenMode as t, checkTokenAlias as u, coerceTokenLiteral as v, createTokenCollection as w, createTokenVariable as x, defaultTokenId as y, defaultTokenValue as z };
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Design tokens (Figma-style "variables"): collections hold modes (e.g. Light / Dark) and
3
+ * typed variables with one value per mode. A value is a literal or an alias to another
4
+ * variable of the same type, possibly in another collection.
5
+ *
6
+ * The state is plain, immutable, JSON-serialisable data. Every operation returns a new state.
7
+ */
8
+ /** A variable's type. */
9
+ type TokenType = 'color' | 'number' | 'string' | 'boolean';
10
+ declare const TOKEN_TYPES: readonly TokenType[];
11
+ /** A resolved value: colours are normalised hex strings (`#rrggbb` or `#rrggbbaa`). */
12
+ type TokenLiteral = string | number | boolean;
13
+ /** A reference to another variable (by id). */
14
+ interface TokenAlias {
15
+ alias: string;
16
+ }
17
+ /** What a variable holds in one mode. */
18
+ type TokenValue = TokenLiteral | TokenAlias;
19
+ interface TokenMode {
20
+ id: string;
21
+ name: string;
22
+ }
23
+ interface TokenCollection {
24
+ id: string;
25
+ name: string;
26
+ /** At least one mode. The first one is the default mode. */
27
+ modes: readonly TokenMode[];
28
+ }
29
+ /**
30
+ * Which properties pickers offer a variable for (figcraft / Figma scope ids). Scopes only
31
+ * filter pickers: binding out of scope still works.
32
+ */
33
+ type TokenScope = 'ALL_SCOPES' | 'ALL_FILLS' | 'FRAME_FILL' | 'SHAPE_FILL' | 'TEXT_FILL' | 'STROKE_COLOR' | 'EFFECT_COLOR' | 'CORNER_RADIUS' | 'WIDTH_HEIGHT' | 'GAP' | 'OPACITY' | 'STROKE_FLOAT' | 'EFFECT_FLOAT' | 'FONT_WEIGHT' | 'FONT_SIZE' | 'LINE_HEIGHT' | 'LETTER_SPACING' | 'PARAGRAPH_SPACING' | 'PARAGRAPH_INDENT' | 'TEXT_CONTENT' | 'FONT_FAMILY' | 'FONT_STYLE';
34
+ interface TokenVariable {
35
+ id: string;
36
+ /** Unique within its collection. `/` separates groups (`color/bg`). */
37
+ name: string;
38
+ collectionId: string;
39
+ type: TokenType;
40
+ /** Value per mode id of the collection. */
41
+ valuesByMode: Readonly<Record<string, TokenValue>>;
42
+ description?: string;
43
+ /** Pickers offer the variable for these scopes; `undefined` = every supported property. */
44
+ scopes?: readonly TokenScope[];
45
+ /** Unit for number variables in CSS / W3C export (`px`, `rem`, `ms`, …). */
46
+ unit?: string;
47
+ }
48
+ interface TokenState {
49
+ collections: readonly TokenCollection[];
50
+ variables: readonly TokenVariable[];
51
+ }
52
+ /**
53
+ * Chosen mode per collection: `{ [collectionId]: modeId }`. Collections not listed (or with an
54
+ * unknown mode) use their default (first) mode.
55
+ */
56
+ type TokenModeContext = Readonly<Record<string, string>>;
57
+ type TokenErrorCode = 'not-found' | 'invalid-name' | 'duplicate-name' | 'name-conflict' | 'invalid-type' | 'invalid-value' | 'type-mismatch' | 'alias-missing' | 'alias-cycle' | 'last-mode' | 'unknown-scope' | 'invalid-input';
58
+ /** Thrown by token operations that are refused; `code` says why. */
59
+ declare class TokenError extends Error {
60
+ readonly code: TokenErrorCode;
61
+ constructor(code: TokenErrorCode, message: string);
62
+ }
63
+ declare function isTokenAlias(value: unknown): value is TokenAlias;
64
+ declare const EMPTY_TOKEN_STATE: TokenState;
65
+
66
+ declare function getTokenCollection(state: TokenState, id: string): TokenCollection | undefined;
67
+ declare function getTokenVariable(state: TokenState, id: string): TokenVariable | undefined;
68
+ /** The collection with this name. */
69
+ declare function findTokenCollection(state: TokenState, name: string): TokenCollection | undefined;
70
+ /** The variable named `name` (in `collectionId` when given, else the first match). */
71
+ declare function findTokenVariable(state: TokenState, name: string, collectionId?: string): TokenVariable | undefined;
72
+ /** The variables of a collection, in order. */
73
+ declare function getCollectionVariables(state: TokenState, collectionId: string): TokenVariable[];
74
+ /** The collection's default (first) mode. */
75
+ declare function getDefaultMode(collection: TokenCollection): TokenMode;
76
+ /** The mode with id `key`, else the one named `key`. */
77
+ declare function findTokenMode(collection: TokenCollection, key: string): TokenMode | undefined;
78
+ /** The mode `collection` is in under `modes` (its chosen mode if valid, else the default). */
79
+ declare function getCurrentMode(collection: TokenCollection, modes: TokenModeContext | undefined): TokenMode;
80
+ /** A new variable's value per type: black, 0, empty, true (figcraft's pinned defaults). */
81
+ declare function defaultTokenValue(type: TokenType): TokenLiteral;
82
+ /** The literal as `type`, or `null` when it does not fit (colours are normalised). */
83
+ declare function coerceTokenLiteral(type: TokenType, value: unknown): TokenLiteral | null;
84
+ /** The type of a literal value (strings that are colours count as strings). */
85
+ declare function literalTokenType(value: TokenLiteral): TokenType;
86
+ /** A short text for a value: hex, number, string, boolean, or `→ name` for an alias. */
87
+ declare function formatTokenValue(state: TokenState, value: TokenValue | undefined): string;
88
+ type TokenResolutionErrorCode = 'missing' | 'cycle' | 'no-value' | 'type-mismatch';
89
+ type TokenResolution = {
90
+ ok: true;
91
+ value: TokenLiteral;
92
+ type: TokenType;
93
+ /** The variable whose literal was used (the end of the alias chain). */
94
+ variable: TokenVariable;
95
+ /** Mode of `variable`'s collection that supplied the value. */
96
+ modeId: string;
97
+ /** Variable ids visited, starting with the requested one. */
98
+ chain: string[];
99
+ } | {
100
+ ok: false;
101
+ code: TokenResolutionErrorCode;
102
+ message: string;
103
+ chain: string[];
104
+ };
105
+ /**
106
+ * Resolves variable `id` under `modes` (collection id → mode id; the default mode otherwise),
107
+ * following aliases. Each variable along the chain is read in its own collection's mode.
108
+ * Cycles, missing variables and type changes along the chain are reported, never thrown.
109
+ */
110
+ declare function resolveToken(state: TokenState, id: string, modes?: TokenModeContext): TokenResolution;
111
+ /** The resolved literal, or `undefined` when it does not resolve. */
112
+ declare function resolveTokenValue(state: TokenState, id: string, modes?: TokenModeContext): TokenLiteral | undefined;
113
+ /** The value of `variableId` in mode `modeId` of its own collection (other collections in their default mode). */
114
+ declare function resolveTokenInMode(state: TokenState, variableId: string, modeId: string): TokenLiteral | undefined;
115
+ /**
116
+ * Why `variable` cannot alias `targetId`, or `null` when it can: the target must exist, have
117
+ * the same type, and not lead back to `variable` through any alias in any mode.
118
+ */
119
+ declare function checkTokenAlias(state: TokenState, variable: Pick<TokenVariable, 'id' | 'type' | 'name'>, targetId: string): TokenError | null;
120
+ declare const TOKEN_SCOPES_BY_TYPE: Readonly<Record<TokenType, readonly TokenScope[]>>;
121
+ /** Whether `scope` is a scope a variable of `type` can be limited to. */
122
+ declare function isTokenScopeKnown(type: TokenType, scope: string): scope is TokenScope;
123
+ /**
124
+ * Canonical scope list: known ids only, no repeats, `undefined` (no limit) when every
125
+ * supported property is named. Unknown ids throw `unknown-scope`.
126
+ */
127
+ declare function normalizeTokenScopes(type: TokenType, scopes: readonly string[] | null | undefined): TokenScope[] | undefined;
128
+ /** Whether pickers offer `variable` for a property of `scope` (no scope: any). */
129
+ declare function isTokenInScope(variable: Pick<TokenVariable, 'scopes'>, scope: TokenScope | undefined): boolean;
130
+ /** Trims each `/`-separated group; throws `invalid-name` when empty or not exportable. */
131
+ declare function normalizeTokenName(name: unknown, what?: string): string;
132
+ type TokenIdFactory = (kind: 'collection' | 'mode' | 'variable') => string;
133
+ /** Default id factory: `crypto.randomUUID`, with a counter fallback. */
134
+ declare const defaultTokenId: TokenIdFactory;
135
+ interface CreateTokenCollectionInput {
136
+ name: string;
137
+ /** Mode names (default `['Default']`). */
138
+ modes?: readonly string[];
139
+ }
140
+ declare function createTokenCollection(state: TokenState, input: CreateTokenCollectionInput, createId?: TokenIdFactory): {
141
+ state: TokenState;
142
+ collection: TokenCollection;
143
+ };
144
+ declare function renameTokenCollection(state: TokenState, id: string, name: string): TokenState;
145
+ /**
146
+ * Deletes variables `ids`. Variables aliasing one of them take its values (per mode: the deleted
147
+ * variable resolved in that mode when it is in the same collection, else in its default mode).
148
+ */
149
+ declare function deleteTokenVariables(state: TokenState, ids: Iterable<string>): {
150
+ state: TokenState;
151
+ deleted: string[];
152
+ };
153
+ /** Deletes a collection and its variables (aliases into it are detached to their values). */
154
+ declare function deleteTokenCollection(state: TokenState, id: string): {
155
+ state: TokenState;
156
+ deleted: string[];
157
+ };
158
+ /**
159
+ * Adds a mode. Variables start with the values of mode `from` (default: the default mode).
160
+ */
161
+ declare function addTokenMode(state: TokenState, collectionId: string, name: string, options?: {
162
+ from?: string;
163
+ }, createId?: TokenIdFactory): {
164
+ state: TokenState;
165
+ mode: TokenMode;
166
+ };
167
+ declare function renameTokenMode(state: TokenState, collectionId: string, modeId: string, name: string): TokenState;
168
+ /** Removes a mode and its values; a collection keeps at least one mode. */
169
+ declare function removeTokenMode(state: TokenState, collectionId: string, modeId: string): TokenState;
170
+ /** Moves a mode to index `to` (clamped). Index 0 makes it the default mode. */
171
+ declare function moveTokenMode(state: TokenState, collectionId: string, modeId: string, to: number): TokenState;
172
+ interface CreateTokenVariableInput {
173
+ collectionId: string;
174
+ name: string;
175
+ type: TokenType;
176
+ /** Value for every mode (literal or `{ alias }`). Default: the type's default. */
177
+ value?: unknown;
178
+ /** Values by mode id or name (win over `value`). */
179
+ values?: Readonly<Record<string, unknown>>;
180
+ description?: string;
181
+ scopes?: readonly string[];
182
+ unit?: string;
183
+ }
184
+ /** A value for `variable`: a normalised literal or a checked alias. Throws when refused. */
185
+ declare function prepareTokenValue(state: TokenState, variable: Pick<TokenVariable, 'id' | 'type' | 'name'>, value: unknown): TokenValue;
186
+ declare function createTokenVariable(state: TokenState, input: CreateTokenVariableInput, createId?: TokenIdFactory): {
187
+ state: TokenState;
188
+ variable: TokenVariable;
189
+ };
190
+ /**
191
+ * Sets a variable's value in one mode (id or name; default: the default mode) to a literal or
192
+ * `{ alias: variableId }`. Aliases must keep the type and not create a cycle.
193
+ */
194
+ declare function setTokenValue(state: TokenState, variableId: string, value: unknown, modeId?: string): TokenState;
195
+ declare function renameTokenVariable(state: TokenState, variableId: string, name: string): TokenState;
196
+ interface UpdateTokenVariableInput {
197
+ description?: string;
198
+ /** `null` clears the limit (every property). */
199
+ scopes?: readonly string[] | null;
200
+ /** `null` clears the unit. */
201
+ unit?: string | null;
202
+ }
203
+ declare function updateTokenVariable(state: TokenState, variableId: string, input: UpdateTokenVariableInput): TokenState;
204
+ interface TokenStateIssue {
205
+ message: string;
206
+ collectionId?: string;
207
+ variableId?: string;
208
+ }
209
+ /**
210
+ * Reads untrusted data (e.g. a saved `TokenState`) and keeps what is valid: junk collections,
211
+ * modes and variables are dropped, bad values replaced by the type's default and alias cycles
212
+ * broken, each with an issue.
213
+ */
214
+ declare function parseTokenState(input: unknown): {
215
+ state: TokenState;
216
+ issues: TokenStateIssue[];
217
+ };
218
+
219
+ export { resolveToken as $, deleteTokenCollection as A, deleteTokenVariables as B, type CreateTokenVariableInput as C, findTokenCollection as D, EMPTY_TOKEN_STATE as E, findTokenMode as F, findTokenVariable as G, formatTokenValue as H, getCollectionVariables as I, getCurrentMode as J, getDefaultMode as K, getTokenCollection as L, getTokenVariable as M, isTokenAlias as N, isTokenInScope as O, isTokenScopeKnown as P, literalTokenType as Q, moveTokenMode as R, normalizeTokenName as S, type TokenState as T, type UpdateTokenVariableInput as U, normalizeTokenScopes as V, prepareTokenValue as W, removeTokenMode as X, renameTokenCollection as Y, renameTokenMode as Z, renameTokenVariable as _, type TokenIdFactory as a, resolveTokenInMode as a0, resolveTokenValue as a1, setTokenValue as a2, updateTokenVariable as a3, type TokenCollection as b, type TokenVariable as c, type TokenModeContext as d, type TokenResolution as e, type TokenLiteral as f, type TokenMode as g, type CreateTokenCollectionInput as h, TOKEN_SCOPES_BY_TYPE as i, TOKEN_TYPES as j, type TokenAlias as k, TokenError as l, type TokenErrorCode as m, type TokenResolutionErrorCode as n, type TokenScope as o, parseTokenState as p, type TokenStateIssue as q, type TokenType as r, type TokenValue as s, addTokenMode as t, checkTokenAlias as u, coerceTokenLiteral as v, createTokenCollection as w, createTokenVariable as x, defaultTokenId as y, defaultTokenValue as z };
@@ -1,3 +1,5 @@
1
+ import { S as StorageAdapter } from '../storage-BpFfspHm.cjs';
2
+ export { I as IdbFactoryLike, a as IndexedDbAdapterOptions, b as InjectedStorageError, L as LocalStorageAdapterOptions, M as MemoryStorage, O as OpfsAdapterOptions, c as OpfsDirectoryLike, d as OpfsFileLike, e as StorageAdapterOptions, f as StorageFailureMode, g as StorageOperation, h as StorageUnavailableError, W as WebStorageLike, i as createIndexedDbAdapter, j as createLocalStorageAdapter, k as createMemoryStorage, l as createOpfsAdapter, m as isIndexedDbAvailable, n as isLocalStorageAvailable, o as isOpfsAvailable, w as withStorageFailures } from '../storage-BpFfspHm.cjs';
1
3
  export { J as JsonObject, L as LoadDocumentOptions, a as LoadDocumentResult, b as LoadReport, c as LoadSectionsOptions, d as LoadSectionsResult, M as MigrateOptions, e as MigrateResult, f as MigrationStep, R as ReadOnlyReason, S as SectionProblem, g as SectionSpec, h as SectionSpecs, i as createLoadReport, j as hasLoadProblems, l as loadDocument, k as loadSections, m as migrateDocument } from '../migrate-iTlm3a8h.cjs';
2
4
 
3
5
  /**
@@ -63,125 +65,6 @@ declare function exponentialBackoff(failures: number, base?: number, max?: numbe
63
65
  */
64
66
  declare function createRecoveryPolicy(options?: RecoveryPolicyOptions): RecoveryPolicy;
65
67
 
66
- /**
67
- * Key/value storage adapters for autosave and crash recovery. Every adapter is
68
- * async, stores strings, feature-detects its backend (an unavailable backend
69
- * rejects every call with `StorageUnavailableError` instead of throwing at
70
- * construction, so SSR and old browsers are safe) and accepts an injectable
71
- * failure mode for tests.
72
- */
73
- type StorageOperation = "get" | "set" | "remove";
74
- /**
75
- * Injected failure: return `true` (or an `Error`) to make that operation fail.
76
- * Example: `failure: (op) => op === "set"` simulates a full disk.
77
- */
78
- type StorageFailureMode = (operation: StorageOperation, key: string) => boolean | Error | undefined | void;
79
- interface StorageAdapter {
80
- /** Short backend name, e.g. `"memory"`, `"localStorage"`, `"indexedDB"`, `"opfs"`. */
81
- readonly kind: string;
82
- /** Whether the backend was found. When `false`, every call rejects. */
83
- readonly available: boolean;
84
- get(key: string): Promise<string | null>;
85
- set(key: string, value: string): Promise<void>;
86
- remove(key: string): Promise<void>;
87
- }
88
- interface StorageAdapterOptions {
89
- failure?: StorageFailureMode;
90
- }
91
- declare class StorageUnavailableError extends Error {
92
- constructor(kind: string);
93
- }
94
- declare class InjectedStorageError extends Error {
95
- constructor(operation: StorageOperation, key: string);
96
- }
97
- /** Wraps an adapter so `failure` can make any of its operations fail. */
98
- declare function withStorageFailures(inner: StorageAdapter, failure: StorageFailureMode): StorageAdapter;
99
- interface MemoryStorage extends StorageAdapter {
100
- /** The underlying map (inspect it in tests). */
101
- readonly entries: Map<string, string>;
102
- }
103
- /** In-memory storage (tests, SSR, or a session-only fallback). */
104
- declare function createMemoryStorage(options?: StorageAdapterOptions & {
105
- initial?: Record<string, string>;
106
- }): MemoryStorage;
107
- /** Minimal `Storage` surface used by the localStorage adapter. */
108
- interface WebStorageLike {
109
- getItem(key: string): string | null;
110
- setItem(key: string, value: string): void;
111
- removeItem(key: string): void;
112
- }
113
- interface LocalStorageAdapterOptions extends StorageAdapterOptions {
114
- /** Storage to use (default `globalThis.localStorage`, e.g. pass `sessionStorage`). */
115
- storage?: WebStorageLike;
116
- }
117
- /** Whether `localStorage` can be used (it throws when site data is blocked). */
118
- declare function isLocalStorageAvailable(): boolean;
119
- /**
120
- * `localStorage` adapter; every key is prefixed with `prefix`. Writes are
121
- * synchronous under the hood, so they complete even inside `pagehide`.
122
- * A full quota rejects the `set` (`QuotaExceededError`).
123
- */
124
- declare function createLocalStorageAdapter(prefix?: string, options?: LocalStorageAdapterOptions): StorageAdapter;
125
- /** Minimal `IDBFactory` surface (the real `indexedDB`, or a fake in tests). */
126
- interface IdbFactoryLike {
127
- open(name: string, version?: number): any;
128
- }
129
- interface IndexedDbAdapterOptions extends StorageAdapterOptions {
130
- /** Object store name (default `"kv"`). */
131
- store?: string;
132
- /** Factory to use (default `globalThis.indexedDB`). */
133
- indexedDB?: IdbFactoryLike;
134
- }
135
- /** Whether `indexedDB` exists in this environment. */
136
- declare function isIndexedDbAvailable(): boolean;
137
- /**
138
- * IndexedDB adapter: one database `name` with a single key/value object store.
139
- * A `set` resolves when its transaction completes (not merely when the request
140
- * succeeds), so a resolved write is durable.
141
- */
142
- declare function createIndexedDbAdapter(name?: string, options?: IndexedDbAdapterOptions): StorageAdapter;
143
- /** Minimal `FileSystemDirectoryHandle` surface used by the OPFS adapter. */
144
- interface OpfsDirectoryLike {
145
- getDirectoryHandle(name: string, options?: {
146
- create?: boolean;
147
- }): Promise<OpfsDirectoryLike>;
148
- getFileHandle(name: string, options?: {
149
- create?: boolean;
150
- }): Promise<OpfsFileLike>;
151
- removeEntry(name: string): Promise<void>;
152
- }
153
- interface OpfsFileLike {
154
- getFile(): Promise<{
155
- text(): Promise<string>;
156
- }>;
157
- createWritable?(): Promise<{
158
- write(data: string): Promise<void>;
159
- close(): Promise<void>;
160
- }>;
161
- /** Rename in place (Chromium, Safari). Used for temp-file + rename writes. */
162
- move?(name: string): Promise<void>;
163
- }
164
- interface OpfsAdapterOptions extends StorageAdapterOptions {
165
- /** Root directory (default `navigator.storage.getDirectory()`). */
166
- root?: () => Promise<OpfsDirectoryLike>;
167
- /** Force the write-then-pointer-swap strategy even when `move` exists. */
168
- disableRename?: boolean;
169
- }
170
- /** Whether the Origin Private File System exists (`navigator.storage.getDirectory`). */
171
- declare function isOpfsAvailable(): boolean;
172
- /**
173
- * Origin Private File System adapter. Values are files in `dir` (created on
174
- * demand), named after the URI-encoded key.
175
- *
176
- * Writes never leave a half-written value behind: where file handles support
177
- * `move`, the value is written to `<file>.tmp` and renamed over `<file>`;
178
- * otherwise it alternates between two slots (`<file>.a` / `<file>.b`) and then
179
- * swaps a pointer file (`<file>.ptr`), so a crash mid-write keeps the previous
180
- * value. Main-thread writes need `createWritable` (missing in some Safari
181
- * versions); without it, `set` rejects with `StorageUnavailableError`.
182
- */
183
- declare function createOpfsAdapter(dir?: string, options?: OpfsAdapterOptions): StorageAdapter;
184
-
185
68
  type AutosaveStatus = "idle" | "dirty" | "saving" | "saved" | "error";
186
69
  interface AutosaveStatusInfo {
187
70
  status: AutosaveStatus;
@@ -344,4 +227,4 @@ interface RevisionTracker {
344
227
  */
345
228
  declare function createRevisionTracker(options?: RevisionTrackerOptions): RevisionTracker;
346
229
 
347
- export { type AutosaveController, type AutosaveControllerOptions, type AutosaveRecovery, type AutosaveStatus, type AutosaveStatusInfo, type DirtyFlagSource, type IdbFactoryLike, type IndexedDbAdapterOptions, InjectedStorageError, type LocalStorageAdapterOptions, type MemoryStorage, type OpfsAdapterOptions, type OpfsDirectoryLike, type OpfsFileLike, type RecoveryAction, type RecoveryMeta, type RecoveryPolicy, type RecoveryPolicyOptions, type RecoveryTickOptions, type RevisionChangeSource, type RevisionTracker, type RevisionTrackerOptions, type StorageAdapter, type StorageAdapterOptions, type StorageFailureMode, type StorageOperation, StorageUnavailableError, type WebStorageLike, createAutosaveController, createIndexedDbAdapter, createLocalStorageAdapter, createMemoryStorage, createOpfsAdapter, createRecoveryPolicy, createRevisionTracker, exponentialBackoff, formatRecoveryMessage, isIndexedDbAvailable, isLocalStorageAvailable, isOpfsAvailable, recoveryMetaKey, withStorageFailures };
230
+ export { type AutosaveController, type AutosaveControllerOptions, type AutosaveRecovery, type AutosaveStatus, type AutosaveStatusInfo, type DirtyFlagSource, type RecoveryAction, type RecoveryMeta, type RecoveryPolicy, type RecoveryPolicyOptions, type RecoveryTickOptions, type RevisionChangeSource, type RevisionTracker, type RevisionTrackerOptions, StorageAdapter, createAutosaveController, createRecoveryPolicy, createRevisionTracker, exponentialBackoff, formatRecoveryMessage, recoveryMetaKey };