@sorb/core 0.1.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 (2) hide show
  1. package/package.json +27 -0
  2. package/src/index.js +101 -0
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@sorb/core",
3
+ "version": "0.1.0",
4
+ "description": "Shared Sorb contract: JSDoc typedefs for the resolved bindable token map and capture schemas, plus the canonical tier ordering. One home so the contract can't drift across the Sorb polyrepo.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "keywords": [
8
+ "sorb",
9
+ "design-tokens",
10
+ "figma",
11
+ "tokens"
12
+ ],
13
+ "homepage": "https://github.com/metatoy/sorb-core#readme",
14
+ "bugs": "https://github.com/metatoy/sorb-core/issues",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/metatoy/sorb-core.git"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "main": "src/index.js",
23
+ "files": [
24
+ "src"
25
+ ],
26
+ "sideEffects": false
27
+ }
package/src/index.js ADDED
@@ -0,0 +1,101 @@
1
+ // @sorb/core — the shared Sorb contract.
2
+ //
3
+ // One published home for the shapes that cross repo boundaries: the resolved
4
+ // bindable token map (Style Dictionary's `sorb/resolved-map` output) and the
5
+ // capture schemas (LayerNode tree, story index). Consolidated here so the
6
+ // contract can't drift across sorb-seed, sorb-juice, and sorb-leaf once the
7
+ // monorepo is split (sorb-rename-migration §3.2).
8
+ //
9
+ // JS-only, JSDoc typedefs — per the hard rules, no TypeScript. The only runtime
10
+ // export is the canonical tier ordering, which the capture annotator and the
11
+ // plugin both rank against.
12
+
13
+ /**
14
+ * Token tiers, most-specific first. Binding precedence: component beats
15
+ * semantic beats primitive.
16
+ * @type {readonly ['component', 'semantic', 'primitive']}
17
+ */
18
+ export const TIERS = Object.freeze(['component', 'semantic', 'primitive'])
19
+
20
+ /**
21
+ * Tier → rank (0 = most specific). Lower wins when several tokens share a value.
22
+ * @type {Readonly<Record<Tier, number>>}
23
+ */
24
+ export const TIER_RANK = Object.freeze({ component: 0, semantic: 1, primitive: 2 })
25
+
26
+ // ─── Shared typedefs ───────────────────────────────────────────────────────────
27
+
28
+ /**
29
+ * @typedef {'primitive' | 'semantic' | 'component'} Tier
30
+ * Which layer of the 3-tier DTCG taxonomy a token belongs to.
31
+ */
32
+
33
+ /**
34
+ * @typedef {'color' | 'dimension' | 'fontFamily' | 'fontWeight' | 'number' | 'string'} TokenType
35
+ * DTCG `$type` of the resolved token (extend as the taxonomy grows).
36
+ */
37
+
38
+ /**
39
+ * A flat map of token name → value.
40
+ * @typedef {Object.<string, string | number>} TokenSet
41
+ */
42
+
43
+ /**
44
+ * One entry of the resolved bindable token map — the single contract produced by
45
+ * Style Dictionary (`sorb/resolved-map`) and consumed by the bridge, the capture
46
+ * annotator, and the plugin. This is THE shape that must not drift.
47
+ * @typedef {Object} ResolvedToken
48
+ * @property {string} id Dotted token id, e.g. `button.primary.bg.default`.
49
+ * @property {string} cssVar The emitted CSS custom property, e.g. `--button-primary-bg-default`.
50
+ * @property {string | number} value Fully resolved value (no `var()` chains).
51
+ * @property {Tier} tier Taxonomy tier (drives binding precedence via TIER_RANK).
52
+ * @property {TokenType} type DTCG `$type`.
53
+ */
54
+
55
+ /**
56
+ * The resolved map as served/written: `.sorb/resolved.json`.
57
+ * @typedef {ResolvedToken[]} ResolvedMap
58
+ */
59
+
60
+ /**
61
+ * A captured CSS value plus the raw string it came from.
62
+ * @typedef {Object} RawValue
63
+ * @property {string} raw The raw CSS string captured from the DOM (e.g. `rgb(15,101,239)`).
64
+ */
65
+
66
+ /**
67
+ * A node in a captured layer tree (Storybook story → Figma-insertable geometry).
68
+ * Produced by capture, annotated in place by the seed annotator, materialized by
69
+ * the plugin.
70
+ * @typedef {Object} LayerNode
71
+ * @property {string} type Figma-ish node type, e.g. `FRAME`, `TEXT`.
72
+ * @property {RawValue[]} [fills] Fill paints (index 0 is the primary fill).
73
+ * @property {RawValue[]} [strokes] Stroke paints.
74
+ * @property {number} [cornerRadius] Corner radius in px.
75
+ * @property {{ color?: RawValue }[]} [effects] Effects (shadows, etc.).
76
+ * @property {LayerNode[]} [children] Child nodes.
77
+ * @property {SorbAnnotation} [sorb] Token bindings attached by the annotator.
78
+ */
79
+
80
+ /**
81
+ * Token bindings the seed annotator stamps onto a matched LayerNode.
82
+ * @typedef {Object} SorbAnnotation
83
+ * @property {Object.<string, string>} tokens
84
+ * role (`fill`/`stroke`/`cornerRadius`/`effectN`) → bound token id.
85
+ * @property {Object.<string, string[]>} candidates
86
+ * role → all token ids whose value matched (the plugin offers these as a switch).
87
+ */
88
+
89
+ /**
90
+ * One story's entry in the capture index (`.sorb/index.json`).
91
+ * @typedef {Object} StoryEntry
92
+ * @property {string} artifact Relative path to the captured artifact (`*.sorb.json`).
93
+ */
94
+
95
+ /**
96
+ * The capture index written to `.sorb/index.json`.
97
+ * @typedef {Object} StoryIndex
98
+ * @property {Object.<string, StoryEntry>} stories storyId → entry.
99
+ */
100
+
101
+ export {}