@oh-just-another/renderer-core 0.57.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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/animation-adapter.d.ts +91 -0
- package/dist/animation-adapter.d.ts.map +1 -0
- package/dist/animation-adapter.js +90 -0
- package/dist/animation-adapter.js.map +1 -0
- package/dist/built-in-renderers.d.ts +6 -0
- package/dist/built-in-renderers.d.ts.map +1 -0
- package/dist/built-in-renderers.js +517 -0
- package/dist/built-in-renderers.js.map +1 -0
- package/dist/constants.d.ts +97 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +115 -0
- package/dist/constants.js.map +1 -0
- package/dist/edge-cache-bitmap.d.ts +34 -0
- package/dist/edge-cache-bitmap.d.ts.map +1 -0
- package/dist/edge-cache-bitmap.js +42 -0
- package/dist/edge-cache-bitmap.js.map +1 -0
- package/dist/edge-cache.d.ts +32 -0
- package/dist/edge-cache.d.ts.map +1 -0
- package/dist/edge-cache.js +90 -0
- package/dist/edge-cache.js.map +1 -0
- package/dist/edge-renderer.d.ts +73 -0
- package/dist/edge-renderer.d.ts.map +1 -0
- package/dist/edge-renderer.js +554 -0
- package/dist/edge-renderer.js.map +1 -0
- package/dist/grid-renderer.d.ts +55 -0
- package/dist/grid-renderer.d.ts.map +1 -0
- package/dist/grid-renderer.js +173 -0
- package/dist/grid-renderer.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/js-rasterizer.d.ts +8 -0
- package/dist/js-rasterizer.d.ts.map +1 -0
- package/dist/js-rasterizer.js +86 -0
- package/dist/js-rasterizer.js.map +1 -0
- package/dist/layer-cache-composite.d.ts +39 -0
- package/dist/layer-cache-composite.d.ts.map +1 -0
- package/dist/layer-cache-composite.js +47 -0
- package/dist/layer-cache-composite.js.map +1 -0
- package/dist/layers.d.ts +14 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/layers.js +2 -0
- package/dist/layers.js.map +1 -0
- package/dist/rasterizer.d.ts +27 -0
- package/dist/rasterizer.d.ts.map +1 -0
- package/dist/rasterizer.js +10 -0
- package/dist/rasterizer.js.map +1 -0
- package/dist/render-target.d.ts +94 -0
- package/dist/render-target.d.ts.map +1 -0
- package/dist/render-target.js +2 -0
- package/dist/render-target.js.map +1 -0
- package/dist/scene-renderer.d.ts +126 -0
- package/dist/scene-renderer.d.ts.map +1 -0
- package/dist/scene-renderer.js +149 -0
- package/dist/scene-renderer.js.map +1 -0
- package/dist/shape-cache-bitmap.d.ts +42 -0
- package/dist/shape-cache-bitmap.d.ts.map +1 -0
- package/dist/shape-cache-bitmap.js +61 -0
- package/dist/shape-cache-bitmap.js.map +1 -0
- package/dist/shape-cache.d.ts +40 -0
- package/dist/shape-cache.d.ts.map +1 -0
- package/dist/shape-cache.js +67 -0
- package/dist/shape-cache.js.map +1 -0
- package/dist/shape-renderer.d.ts +36 -0
- package/dist/shape-renderer.d.ts.map +1 -0
- package/dist/shape-renderer.js +15 -0
- package/dist/shape-renderer.js.map +1 -0
- package/dist/text-editing.d.ts +81 -0
- package/dist/text-editing.d.ts.map +1 -0
- package/dist/text-editing.js +191 -0
- package/dist/text-editing.js.map +1 -0
- package/dist/text-layout.d.ts +44 -0
- package/dist/text-layout.d.ts.map +1 -0
- package/dist/text-layout.js +57 -0
- package/dist/text-layout.js.map +1 -0
- package/dist/text-shaper.d.ts +53 -0
- package/dist/text-shaper.d.ts.map +1 -0
- package/dist/text-shaper.js +19 -0
- package/dist/text-shaper.js.map +1 -0
- package/dist/tile-renderer.d.ts +126 -0
- package/dist/tile-renderer.d.ts.map +1 -0
- package/dist/tile-renderer.js +192 -0
- package/dist/tile-renderer.js.map +1 -0
- package/dist/worker-render.d.ts +54 -0
- package/dist/worker-render.d.ts.map +1 -0
- package/dist/worker-render.js +8 -0
- package/dist/worker-render.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tile-based rendering scaffold. The scene is split into a fixed-size
|
|
3
|
+
* world-space grid; each tile is rasterised once into an
|
|
4
|
+
* OffscreenCanvas / ImageBitmap and re-composited on pan without
|
|
5
|
+
* re-rendering. Zoom changes invalidate the bucket.
|
|
6
|
+
*
|
|
7
|
+
* This file ships the constants and cache interface so backends can
|
|
8
|
+
* adopt the API.
|
|
9
|
+
*/
|
|
10
|
+
/** Side length of one tile in world units. */
|
|
11
|
+
export const TILE_SIZE = 2048;
|
|
12
|
+
/**
|
|
13
|
+
* Hard upper bound on the tile cache footprint (256 MB) — the
|
|
14
|
+
* practical ceiling on desktop browsers. Used as the clamp ceiling of
|
|
15
|
+
* {@link MAX_TILE_CACHE_BYTES}; the actual cap can be lower on
|
|
16
|
+
* low-memory devices.
|
|
17
|
+
*/
|
|
18
|
+
const TILE_CACHE_HARD_CEILING = 256 * 1024 * 1024;
|
|
19
|
+
/** Bytes per GB of host RAM that the tile cache is allowed to claim. */
|
|
20
|
+
const TILE_CACHE_BYTES_PER_GB = 64 * 1024 * 1024;
|
|
21
|
+
/**
|
|
22
|
+
* Guess how many GiB of RAM the host has. Reads `navigator.deviceMemory`
|
|
23
|
+
* when exposed (Chrome — rounded to {0.25, 0.5, 1, 2, 4, 8}).
|
|
24
|
+
* Falls back to a `navigator.hardwareConcurrency` proxy on Safari /
|
|
25
|
+
* Firefox where deviceMemory is unavailable: 8+ cores → desktop class
|
|
26
|
+
* (4 GiB), 4-7 → mid-range phone / laptop (2 GiB), <4 → low-end (1 GiB).
|
|
27
|
+
*
|
|
28
|
+
* SSR / Node (no `navigator`) returns 4 for headless / test environments.
|
|
29
|
+
*/
|
|
30
|
+
const guessDeviceMemoryGB = () => {
|
|
31
|
+
if (typeof navigator === "undefined")
|
|
32
|
+
return 4;
|
|
33
|
+
const nav = navigator;
|
|
34
|
+
if (typeof nav.deviceMemory === "number" && nav.deviceMemory > 0) {
|
|
35
|
+
return nav.deviceMemory;
|
|
36
|
+
}
|
|
37
|
+
const cores = typeof nav.hardwareConcurrency === "number" ? nav.hardwareConcurrency : 4;
|
|
38
|
+
if (cores >= 8)
|
|
39
|
+
return 4;
|
|
40
|
+
if (cores >= 4)
|
|
41
|
+
return 2;
|
|
42
|
+
return 1;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Memory cap for cached tile bitmaps (bytes), adaptive per device.
|
|
46
|
+
*
|
|
47
|
+
* Formula: `min(256 MB, deviceMemoryGB × 64 MB)`.
|
|
48
|
+
* • iPhone Safari (no deviceMemory; A15 = 6 cores) → 2 GiB → 128 MB
|
|
49
|
+
* • Android low-RAM (deviceMemory=2) → 128 MB
|
|
50
|
+
* • Android mid-range (deviceMemory=4) → 256 MB
|
|
51
|
+
* • Desktop (deviceMemory=8 / hardwareConcurrency=8+) → 256 MB (cap)
|
|
52
|
+
* • Very low-end (deviceMemory=0.5) → 32 MB
|
|
53
|
+
*
|
|
54
|
+
* The adaptive cap caps the upper bound proportionally to device
|
|
55
|
+
* memory, leaving headroom for the rest of the JS heap.
|
|
56
|
+
*
|
|
57
|
+
* Evaluated once at module load — navigator state doesn't change during
|
|
58
|
+
* a session. Hosts that need a different cap can pass
|
|
59
|
+
* `new InMemoryTileCache(<custom bytes>)` directly.
|
|
60
|
+
*/
|
|
61
|
+
export const MAX_TILE_CACHE_BYTES = Math.min(TILE_CACHE_HARD_CEILING, guessDeviceMemoryGB() * TILE_CACHE_BYTES_PER_GB);
|
|
62
|
+
/**
|
|
63
|
+
* Below this zoom we drop to LOD: cache tiles render only AABBs
|
|
64
|
+
* (no stroke / text / detail) so 1 M+ shape scenes stay smooth.
|
|
65
|
+
*/
|
|
66
|
+
export const LOD_THRESHOLD = 0.25;
|
|
67
|
+
const keyOf = (k) => `${k.col},${k.row}@${k.zoom}`;
|
|
68
|
+
/**
|
|
69
|
+
* Reference TileCache backed by a Map with LRU eviction by total
|
|
70
|
+
* bytes. Bitmap-agnostic — the eviction logic tracks the `bytes`
|
|
71
|
+
* field reported by the host; whatever stores ImageBitmap /
|
|
72
|
+
* OffscreenCanvas / SharedArrayBuffer is the host's call.
|
|
73
|
+
*
|
|
74
|
+
* Invalidation is shape-id-indexed: every `set` also updates a
|
|
75
|
+
* reverse index `Map<ElementId, Set<tileKey>>` so the editor's
|
|
76
|
+
* patch hook can call `invalidateForElement(id)` in O(touched tiles)
|
|
77
|
+
* instead of scanning every tile.
|
|
78
|
+
*/
|
|
79
|
+
export class InMemoryTileCache {
|
|
80
|
+
entries = new Map();
|
|
81
|
+
tilesByElement = new Map();
|
|
82
|
+
bytes = 0;
|
|
83
|
+
cap;
|
|
84
|
+
constructor(byteCap = MAX_TILE_CACHE_BYTES) {
|
|
85
|
+
this.cap = byteCap;
|
|
86
|
+
}
|
|
87
|
+
get bytesUsed() {
|
|
88
|
+
return this.bytes;
|
|
89
|
+
}
|
|
90
|
+
get(key) {
|
|
91
|
+
const id = keyOf(key);
|
|
92
|
+
const e = this.entries.get(id);
|
|
93
|
+
if (!e)
|
|
94
|
+
return undefined;
|
|
95
|
+
// Touch — re-insert at the tail to mark recently used.
|
|
96
|
+
this.entries.delete(id);
|
|
97
|
+
this.entries.set(id, e);
|
|
98
|
+
return e;
|
|
99
|
+
}
|
|
100
|
+
set(entry) {
|
|
101
|
+
const id = keyOf(entry.key);
|
|
102
|
+
const prior = this.entries.get(id);
|
|
103
|
+
if (prior) {
|
|
104
|
+
this.bytes -= prior.bytes;
|
|
105
|
+
for (const sid of prior.elements)
|
|
106
|
+
this.tilesByElement.get(sid)?.delete(id);
|
|
107
|
+
}
|
|
108
|
+
this.entries.set(id, entry);
|
|
109
|
+
this.bytes += entry.bytes;
|
|
110
|
+
for (const sid of entry.elements) {
|
|
111
|
+
let bucket = this.tilesByElement.get(sid);
|
|
112
|
+
if (!bucket) {
|
|
113
|
+
bucket = new Set();
|
|
114
|
+
this.tilesByElement.set(sid, bucket);
|
|
115
|
+
}
|
|
116
|
+
bucket.add(id);
|
|
117
|
+
}
|
|
118
|
+
this.evictIfOverCap();
|
|
119
|
+
}
|
|
120
|
+
invalidateForElement(elementId) {
|
|
121
|
+
const bucket = this.tilesByElement.get(elementId);
|
|
122
|
+
if (!bucket)
|
|
123
|
+
return;
|
|
124
|
+
for (const tileId of bucket) {
|
|
125
|
+
const e = this.entries.get(tileId);
|
|
126
|
+
if (!e)
|
|
127
|
+
continue;
|
|
128
|
+
this.entries.delete(tileId);
|
|
129
|
+
this.bytes -= e.bytes;
|
|
130
|
+
for (const sid of e.elements) {
|
|
131
|
+
if (sid !== elementId)
|
|
132
|
+
this.tilesByElement.get(sid)?.delete(tileId);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
this.tilesByElement.delete(elementId);
|
|
136
|
+
}
|
|
137
|
+
invalidateRect(rect) {
|
|
138
|
+
const rMaxX = rect.x + rect.width;
|
|
139
|
+
const rMaxY = rect.y + rect.height;
|
|
140
|
+
for (const [tileId, entry] of [...this.entries]) {
|
|
141
|
+
const b = entry.bounds;
|
|
142
|
+
const bMaxX = b.x + b.width;
|
|
143
|
+
const bMaxY = b.y + b.height;
|
|
144
|
+
const disjoint = bMaxX <= rect.x || b.x >= rMaxX || bMaxY <= rect.y || b.y >= rMaxY;
|
|
145
|
+
if (disjoint)
|
|
146
|
+
continue;
|
|
147
|
+
this.entries.delete(tileId);
|
|
148
|
+
this.bytes -= entry.bytes;
|
|
149
|
+
for (const sid of entry.elements)
|
|
150
|
+
this.tilesByElement.get(sid)?.delete(tileId);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
clear() {
|
|
154
|
+
this.entries.clear();
|
|
155
|
+
this.tilesByElement.clear();
|
|
156
|
+
this.bytes = 0;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Convenience hook for the editor's patch pipeline. Looks at a
|
|
160
|
+
* scene Patch and invalidates touched tiles via the right
|
|
161
|
+
* cheap path:
|
|
162
|
+
* • shape removed → invalidateForElement (id still in reverse index)
|
|
163
|
+
* • shape added → invalidateRect (no id yet — drop tiles that
|
|
164
|
+
* touch the new shape's bounds)
|
|
165
|
+
* • shape moved → both: removeForElement (old tiles) + rect
|
|
166
|
+
* (new bounds)
|
|
167
|
+
* Caller computes the bounds via `getElementWorldBounds(before|after)`
|
|
168
|
+
* since this package is pure and doesn't know about Element geometry.
|
|
169
|
+
*/
|
|
170
|
+
invalidateForPatch(options) {
|
|
171
|
+
if (options.removedElementId)
|
|
172
|
+
this.invalidateForElement(options.removedElementId);
|
|
173
|
+
if (options.beforeBounds)
|
|
174
|
+
this.invalidateRect(options.beforeBounds);
|
|
175
|
+
if (options.afterBounds)
|
|
176
|
+
this.invalidateRect(options.afterBounds);
|
|
177
|
+
}
|
|
178
|
+
evictIfOverCap() {
|
|
179
|
+
if (this.bytes <= this.cap)
|
|
180
|
+
return;
|
|
181
|
+
// Map preserves insertion order — oldest entry first.
|
|
182
|
+
for (const [id, entry] of this.entries) {
|
|
183
|
+
if (this.bytes <= this.cap)
|
|
184
|
+
break;
|
|
185
|
+
this.entries.delete(id);
|
|
186
|
+
this.bytes -= entry.bytes;
|
|
187
|
+
for (const sid of entry.elements)
|
|
188
|
+
this.tilesByElement.get(sid)?.delete(id);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=tile-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tile-renderer.js","sourceRoot":"","sources":["../src/tile-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Bounds } from "@oh-just-another/types";
|
|
2
|
+
import type { Scene } from "@oh-just-another/scene";
|
|
3
|
+
/**
|
|
4
|
+
* Worker-backed renderer protocol. Defines the postMessage contract between
|
|
5
|
+
* the main-thread orchestrator and an OffscreenCanvas worker that owns a
|
|
6
|
+
* layer of the scene. Wired up via `EditorOptions.workers` per backend:
|
|
7
|
+
*
|
|
8
|
+
* workers: {
|
|
9
|
+
* canvas2d: true, // OffscreenCanvas in worker
|
|
10
|
+
* webgl: false,
|
|
11
|
+
* textShaper: true, // shared text-shaper worker
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
export type WorkerRenderMessage = {
|
|
15
|
+
readonly type: "init";
|
|
16
|
+
/** Transferred canvas. */
|
|
17
|
+
readonly canvas: unknown;
|
|
18
|
+
readonly width: number;
|
|
19
|
+
readonly height: number;
|
|
20
|
+
readonly dpr: number;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: "resize";
|
|
23
|
+
readonly width: number;
|
|
24
|
+
readonly height: number;
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: "frame";
|
|
27
|
+
/** Serialised scene patches applied since the last frame. */
|
|
28
|
+
readonly patches: readonly unknown[];
|
|
29
|
+
/** World-space dirty rect; main re-uses this when compositing. */
|
|
30
|
+
readonly dirtyWorld?: Bounds;
|
|
31
|
+
} | {
|
|
32
|
+
readonly type: "snapshot";
|
|
33
|
+
readonly scene: Scene;
|
|
34
|
+
readonly dpr: number;
|
|
35
|
+
};
|
|
36
|
+
export type WorkerRenderResponse = {
|
|
37
|
+
readonly type: "ready";
|
|
38
|
+
} | {
|
|
39
|
+
readonly type: "frame-done";
|
|
40
|
+
/** ImageBitmap of the rendered layer, transferable. */
|
|
41
|
+
readonly bitmap: unknown;
|
|
42
|
+
readonly dirtyWorld?: Bounds;
|
|
43
|
+
} | {
|
|
44
|
+
readonly type: "error";
|
|
45
|
+
readonly message: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Auto-enable threshold — when the scene crosses this size and the
|
|
49
|
+
* host opted into workers, the editor moves the main canvas to a
|
|
50
|
+
* worker. Below the threshold, in-thread rendering is cheaper than
|
|
51
|
+
* the postMessage overhead.
|
|
52
|
+
*/
|
|
53
|
+
export declare const WORKER_AUTO_THRESHOLD = 5000;
|
|
54
|
+
//# sourceMappingURL=worker-render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-render.d.ts","sourceRoot":"","sources":["../src/worker-render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5E;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;IACrC,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IACE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,OAAQ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-enable threshold — when the scene crosses this size and the
|
|
3
|
+
* host opted into workers, the editor moves the main canvas to a
|
|
4
|
+
* worker. Below the threshold, in-thread rendering is cheaper than
|
|
5
|
+
* the postMessage overhead.
|
|
6
|
+
*/
|
|
7
|
+
export const WORKER_AUTO_THRESHOLD = 5_000;
|
|
8
|
+
//# sourceMappingURL=worker-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-render.js","sourceRoot":"","sources":["../src/worker-render.ts"],"names":[],"mappings":"AA4CA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@oh-just-another/renderer-core",
|
|
3
|
+
"version": "0.57.0",
|
|
4
|
+
"description": "renderer-core package",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Rustam Garifulin <rustam@n69.in>",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/oh-just-another/diagram.git",
|
|
10
|
+
"directory": "packages/renderer-core"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/oh-just-another/diagram#readme",
|
|
13
|
+
"bugs": "https://github.com/oh-just-another/diagram/issues",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"diagram",
|
|
16
|
+
"canvas",
|
|
17
|
+
"svg",
|
|
18
|
+
"editor",
|
|
19
|
+
"graph",
|
|
20
|
+
"drawing"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"CHANGELOG.md"
|
|
36
|
+
],
|
|
37
|
+
"sideEffects": false,
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@oh-just-another/types": "0.57.0",
|
|
43
|
+
"@oh-just-another/scene": "0.57.0",
|
|
44
|
+
"@oh-just-another/math": "0.57.0",
|
|
45
|
+
"@oh-just-another/tokens": "0.57.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -b tsconfig.build.json",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"bench": "vitest bench --run",
|
|
53
|
+
"lint": "eslint src tests",
|
|
54
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
55
|
+
}
|
|
56
|
+
}
|