@glissade/scene 0.46.0 → 0.47.0-pre.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.
- package/dist/describe.d.ts +42 -1
- package/dist/describe.js +142 -3
- package/package.json +2 -2
package/dist/describe.d.ts
CHANGED
|
@@ -114,6 +114,27 @@ interface DescribedHelper {
|
|
|
114
114
|
/** Runnable example snippets — see {@link DescribedNode.examples}. */
|
|
115
115
|
examples?: readonly string[];
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* One entry in the {@link ApiManifest.surface} taxonomy (0.47 "verifiable
|
|
119
|
+
* ground-truth"): a single window.glissade export, tagged with how a consumer
|
|
120
|
+
* reaches it. This is the ONE machine-readable truth for the IIFE surface that
|
|
121
|
+
* both `gs describe --lint` (the drift guard vs the real `@glissade/browser`
|
|
122
|
+
* bundle) and `gs types --global` (the ambient `window.glissade` `.d.ts`) read —
|
|
123
|
+
* so the curated helper/node lists can't silently drift from what actually ships
|
|
124
|
+
* on `window.glissade`, and the no-build author gets a typed global surface.
|
|
125
|
+
*/
|
|
126
|
+
interface SurfaceEntry {
|
|
127
|
+
/** The export name — also the `window.glissade.<name>` global on the IIFE. */
|
|
128
|
+
name: string;
|
|
129
|
+
/** `'value'` = a runtime binding on the bundle (a class / function / object); `'type'` = a TS type-only name that erases at runtime (opaque, referenced by signatures). */
|
|
130
|
+
kind: 'value' | 'type';
|
|
131
|
+
/** `true` when it is reachable as `window.glissade.<name>` on the single-file IIFE bundle. */
|
|
132
|
+
iife: boolean;
|
|
133
|
+
/** How to consume it: `'constructor'` needs `new`, `'function'` is a plain call, `'object'` is a value namespace (e.g. `easings`), `'type'` is type-only. */
|
|
134
|
+
form: 'constructor' | 'function' | 'object' | 'type';
|
|
135
|
+
/** Documented positional-arg count for a callable (parsed from its usage), when known — absent for value objects and types. */
|
|
136
|
+
arity?: number;
|
|
137
|
+
}
|
|
117
138
|
/** The full machine-readable manifest `describe()` returns. */
|
|
118
139
|
interface ApiManifest {
|
|
119
140
|
version: string;
|
|
@@ -139,7 +160,27 @@ interface ApiManifest {
|
|
|
139
160
|
subpaths: {
|
|
140
161
|
[entry: string]: string;
|
|
141
162
|
};
|
|
163
|
+
/**
|
|
164
|
+
* (0.47 "verifiable ground-truth") The window.glissade runtime SURFACE taxonomy:
|
|
165
|
+
* one machine-readable enumeration of every export a no-build `<script src>`
|
|
166
|
+
* author reaches on the IIFE — node constructors, helper/factory functions, the
|
|
167
|
+
* core callables (`timeline`/`createScene`/`track`/`evaluate`/…), value objects
|
|
168
|
+
* (`easings`), and the opaque type-only names signatures reference. PURELY
|
|
169
|
+
* ADDITIVE + generated from the same curated registries the rest of the manifest
|
|
170
|
+
* is (so it can't drift), and OFF the base embed (describe is tree-shaken off the
|
|
171
|
+
* base scene index) — zero determinism/render-path cost. Consumed by
|
|
172
|
+
* `gs describe --lint` and `gs types --global`. Optional so a manifest captured
|
|
173
|
+
* before 0.47 (no `surface`) still type-checks.
|
|
174
|
+
*/
|
|
175
|
+
surface?: SurfaceEntry[];
|
|
142
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* Parse the documented positional-arg count from a helper `usage` string — the
|
|
179
|
+
* count of top-level comma-separated params in its FIRST `(...)` call group
|
|
180
|
+
* (depth-tracked so nested `()`/`[]`/`{}`/`<>` in a param type don't miscount).
|
|
181
|
+
* Used to stamp {@link SurfaceEntry.arity} and to drift-check runtime arity.
|
|
182
|
+
*/
|
|
183
|
+
declare function usageArity(usage: string): number | undefined;
|
|
143
184
|
/**
|
|
144
185
|
* Build the machine-readable API manifest from the live registries (§4.4). Pure
|
|
145
186
|
* introspection: instantiate each built-in node once to read its registered track
|
|
@@ -165,4 +206,4 @@ declare function registerExamples(corpus: {
|
|
|
165
206
|
}): void;
|
|
166
207
|
declare function describe(opts?: DescribeOptions): ApiManifest;
|
|
167
208
|
//#endregion
|
|
168
|
-
export { ApiManifest, DescribeOptions, DescribedBuilderMethod, DescribedComponent, DescribedHelper, DescribedNode, DescribedProp, describe, registerExamples };
|
|
209
|
+
export { ApiManifest, DescribeOptions, DescribedBuilderMethod, DescribedComponent, DescribedHelper, DescribedNode, DescribedProp, SurfaceEntry, describe, registerExamples, usageArity };
|
package/dist/describe.js
CHANGED
|
@@ -23,8 +23,146 @@ import { easings, listValueTypes } from "@glissade/core";
|
|
|
23
23
|
* never pulled onto the base embed path — a scene that never calls `describe()`
|
|
24
24
|
* pays zero bytes for it.
|
|
25
25
|
*/
|
|
26
|
-
const RAW_VERSION = "0.
|
|
26
|
+
const RAW_VERSION = "0.47.0-pre.0";
|
|
27
27
|
const PACKAGE_VERSION = RAW_VERSION.includes("GLISSADE_".concat("VERSION")) ? "0.0.0-dev" : RAW_VERSION;
|
|
28
|
+
/**
|
|
29
|
+
* Parse the documented positional-arg count from a helper `usage` string — the
|
|
30
|
+
* count of top-level comma-separated params in its FIRST `(...)` call group
|
|
31
|
+
* (depth-tracked so nested `()`/`[]`/`{}`/`<>` in a param type don't miscount).
|
|
32
|
+
* Used to stamp {@link SurfaceEntry.arity} and to drift-check runtime arity.
|
|
33
|
+
*/
|
|
34
|
+
function usageArity(usage) {
|
|
35
|
+
const open = usage.indexOf("(");
|
|
36
|
+
if (open < 0) return void 0;
|
|
37
|
+
let depth = 0;
|
|
38
|
+
const params = [];
|
|
39
|
+
let cur = "";
|
|
40
|
+
for (let i = open; i < usage.length; i++) {
|
|
41
|
+
const c = usage[i];
|
|
42
|
+
if (c === "(" || c === "[" || c === "{" || c === "<") {
|
|
43
|
+
depth++;
|
|
44
|
+
if (depth === 1) continue;
|
|
45
|
+
} else if (c === ")" || c === "]" || c === "}" || c === ">") {
|
|
46
|
+
depth--;
|
|
47
|
+
if (depth === 0) {
|
|
48
|
+
if (cur.trim()) params.push(cur);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (depth === 1 && c === ",") {
|
|
53
|
+
params.push(cur);
|
|
54
|
+
cur = "";
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (depth >= 1) cur += c;
|
|
58
|
+
}
|
|
59
|
+
return params.filter((p) => p.trim().length > 0).length;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The window.glissade CONSTRUCTOR nodes — reached with `new` (`new glissade.Rect(…)`).
|
|
63
|
+
* The layout FACTORIES (Stack/Row/Column) + the build-time fan-outs (Grid/Chart/…)
|
|
64
|
+
* are plain calls and live in {@link HELPERS}, so they aren't here.
|
|
65
|
+
*/
|
|
66
|
+
const SURFACE_CONSTRUCTORS = [
|
|
67
|
+
"Group",
|
|
68
|
+
"Rect",
|
|
69
|
+
"Circle",
|
|
70
|
+
"Path",
|
|
71
|
+
"Text",
|
|
72
|
+
"Image",
|
|
73
|
+
"Video",
|
|
74
|
+
"Layout"
|
|
75
|
+
];
|
|
76
|
+
/**
|
|
77
|
+
* The core callables that are `window.glissade.<name>` globals but are neither a
|
|
78
|
+
* node constructor nor a curated {@link HELPERS} factory — the authoring entry
|
|
79
|
+
* points (`timeline`/`createScene`/`track`/`evaluate`/`stagger`) + `describe`
|
|
80
|
+
* itself. `arity` is the documented positional-arg count.
|
|
81
|
+
*/
|
|
82
|
+
const SURFACE_CORE = [
|
|
83
|
+
{
|
|
84
|
+
name: "timeline",
|
|
85
|
+
arity: 1
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "createScene",
|
|
89
|
+
arity: 1
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "track",
|
|
93
|
+
arity: 3
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "evaluate",
|
|
97
|
+
arity: 3
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "stagger",
|
|
101
|
+
arity: 3
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "describe",
|
|
105
|
+
arity: 0
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
/** Value exports that are runtime OBJECTS (not callable): the easing registry. */
|
|
109
|
+
const SURFACE_VALUE_OBJECTS = ["easings"];
|
|
110
|
+
/**
|
|
111
|
+
* The opaque, type-ONLY names the API surface references (they erase at runtime —
|
|
112
|
+
* `window.glissade.Paint` is `undefined`). `gs types --global` emits a best-effort
|
|
113
|
+
* alias per name; `gs describe --lint` guards they stay type-only (a type surfaced
|
|
114
|
+
* as a callable value is the ClipRegion-class drift this catches).
|
|
115
|
+
*/
|
|
116
|
+
const SURFACE_TYPE_ONLY = [
|
|
117
|
+
"Paint",
|
|
118
|
+
"PathValue",
|
|
119
|
+
"FontAxes"
|
|
120
|
+
];
|
|
121
|
+
/**
|
|
122
|
+
* Assemble the {@link SurfaceEntry} taxonomy from the same curated registries the
|
|
123
|
+
* rest of the manifest is built from (node factories + {@link HELPERS} + the core
|
|
124
|
+
* callables), so it can't drift. Deterministic: deduped by name, sorted.
|
|
125
|
+
*/
|
|
126
|
+
function buildSurface() {
|
|
127
|
+
const out = [];
|
|
128
|
+
for (const name of SURFACE_CONSTRUCTORS) out.push({
|
|
129
|
+
name,
|
|
130
|
+
kind: "value",
|
|
131
|
+
iife: true,
|
|
132
|
+
form: "constructor"
|
|
133
|
+
});
|
|
134
|
+
for (const h of HELPERS) {
|
|
135
|
+
const arity = usageArity(h.usage);
|
|
136
|
+
out.push({
|
|
137
|
+
name: h.name,
|
|
138
|
+
kind: "value",
|
|
139
|
+
iife: true,
|
|
140
|
+
form: "function",
|
|
141
|
+
...arity !== void 0 ? { arity } : {}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
for (const c of SURFACE_CORE) out.push({
|
|
145
|
+
name: c.name,
|
|
146
|
+
kind: "value",
|
|
147
|
+
iife: true,
|
|
148
|
+
form: "function",
|
|
149
|
+
arity: c.arity
|
|
150
|
+
});
|
|
151
|
+
for (const name of SURFACE_VALUE_OBJECTS) out.push({
|
|
152
|
+
name,
|
|
153
|
+
kind: "value",
|
|
154
|
+
iife: true,
|
|
155
|
+
form: "object"
|
|
156
|
+
});
|
|
157
|
+
for (const name of SURFACE_TYPE_ONLY) out.push({
|
|
158
|
+
name,
|
|
159
|
+
kind: "type",
|
|
160
|
+
iife: false,
|
|
161
|
+
form: "type"
|
|
162
|
+
});
|
|
163
|
+
const seen = /* @__PURE__ */ new Set();
|
|
164
|
+
return out.filter((e) => seen.has(e.name) ? false : (seen.add(e.name), true)).sort((a, b) => a.name.localeCompare(b.name));
|
|
165
|
+
}
|
|
28
166
|
/** Arity of a value type's numeric repr: vec2/vec2-arc → 2, number → 1; others (color/paint/path/string/boolean) carry no scalar arity. */
|
|
29
167
|
function arityOf(type) {
|
|
30
168
|
if (type === "number") return 1;
|
|
@@ -568,8 +706,9 @@ function describe(opts = {}) {
|
|
|
568
706
|
props: mapComponentProps(c.props)
|
|
569
707
|
})),
|
|
570
708
|
createScene: "createScene({ size: { w, h }, children: Node[] }): Scene — media assets are declared on the Timeline document: timeline({ assets: { <id>: { kind: 'image'|'video', url } } }); an Image/Video node's `assetId` names an entry here.",
|
|
571
|
-
subpaths: SUBPATHS
|
|
709
|
+
subpaths: SUBPATHS,
|
|
710
|
+
surface: buildSurface()
|
|
572
711
|
};
|
|
573
712
|
}
|
|
574
713
|
//#endregion
|
|
575
|
-
export { describe, registerExamples };
|
|
714
|
+
export { describe, registerExamples, usageArity };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/scene",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0-pre.0",
|
|
4
4
|
"description": "glissade scene graph: nodes, transforms, DisplayList emission. Renderer-agnostic; zero DOM/Node dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
],
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"yoga-layout": "^3.2.1",
|
|
80
|
-
"@glissade/core": "0.
|
|
80
|
+
"@glissade/core": "0.47.0-pre.0"
|
|
81
81
|
},
|
|
82
82
|
"repository": {
|
|
83
83
|
"type": "git",
|