@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.
Files changed (93) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +40 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/animation-adapter.d.ts +91 -0
  6. package/dist/animation-adapter.d.ts.map +1 -0
  7. package/dist/animation-adapter.js +90 -0
  8. package/dist/animation-adapter.js.map +1 -0
  9. package/dist/built-in-renderers.d.ts +6 -0
  10. package/dist/built-in-renderers.d.ts.map +1 -0
  11. package/dist/built-in-renderers.js +517 -0
  12. package/dist/built-in-renderers.js.map +1 -0
  13. package/dist/constants.d.ts +97 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +115 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/edge-cache-bitmap.d.ts +34 -0
  18. package/dist/edge-cache-bitmap.d.ts.map +1 -0
  19. package/dist/edge-cache-bitmap.js +42 -0
  20. package/dist/edge-cache-bitmap.js.map +1 -0
  21. package/dist/edge-cache.d.ts +32 -0
  22. package/dist/edge-cache.d.ts.map +1 -0
  23. package/dist/edge-cache.js +90 -0
  24. package/dist/edge-cache.js.map +1 -0
  25. package/dist/edge-renderer.d.ts +73 -0
  26. package/dist/edge-renderer.d.ts.map +1 -0
  27. package/dist/edge-renderer.js +554 -0
  28. package/dist/edge-renderer.js.map +1 -0
  29. package/dist/grid-renderer.d.ts +55 -0
  30. package/dist/grid-renderer.d.ts.map +1 -0
  31. package/dist/grid-renderer.js +173 -0
  32. package/dist/grid-renderer.js.map +1 -0
  33. package/dist/index.d.ts +37 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +24 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/js-rasterizer.d.ts +8 -0
  38. package/dist/js-rasterizer.d.ts.map +1 -0
  39. package/dist/js-rasterizer.js +86 -0
  40. package/dist/js-rasterizer.js.map +1 -0
  41. package/dist/layer-cache-composite.d.ts +39 -0
  42. package/dist/layer-cache-composite.d.ts.map +1 -0
  43. package/dist/layer-cache-composite.js +47 -0
  44. package/dist/layer-cache-composite.js.map +1 -0
  45. package/dist/layers.d.ts +14 -0
  46. package/dist/layers.d.ts.map +1 -0
  47. package/dist/layers.js +2 -0
  48. package/dist/layers.js.map +1 -0
  49. package/dist/rasterizer.d.ts +27 -0
  50. package/dist/rasterizer.d.ts.map +1 -0
  51. package/dist/rasterizer.js +10 -0
  52. package/dist/rasterizer.js.map +1 -0
  53. package/dist/render-target.d.ts +94 -0
  54. package/dist/render-target.d.ts.map +1 -0
  55. package/dist/render-target.js +2 -0
  56. package/dist/render-target.js.map +1 -0
  57. package/dist/scene-renderer.d.ts +126 -0
  58. package/dist/scene-renderer.d.ts.map +1 -0
  59. package/dist/scene-renderer.js +149 -0
  60. package/dist/scene-renderer.js.map +1 -0
  61. package/dist/shape-cache-bitmap.d.ts +42 -0
  62. package/dist/shape-cache-bitmap.d.ts.map +1 -0
  63. package/dist/shape-cache-bitmap.js +61 -0
  64. package/dist/shape-cache-bitmap.js.map +1 -0
  65. package/dist/shape-cache.d.ts +40 -0
  66. package/dist/shape-cache.d.ts.map +1 -0
  67. package/dist/shape-cache.js +67 -0
  68. package/dist/shape-cache.js.map +1 -0
  69. package/dist/shape-renderer.d.ts +36 -0
  70. package/dist/shape-renderer.d.ts.map +1 -0
  71. package/dist/shape-renderer.js +15 -0
  72. package/dist/shape-renderer.js.map +1 -0
  73. package/dist/text-editing.d.ts +81 -0
  74. package/dist/text-editing.d.ts.map +1 -0
  75. package/dist/text-editing.js +191 -0
  76. package/dist/text-editing.js.map +1 -0
  77. package/dist/text-layout.d.ts +44 -0
  78. package/dist/text-layout.d.ts.map +1 -0
  79. package/dist/text-layout.js +57 -0
  80. package/dist/text-layout.js.map +1 -0
  81. package/dist/text-shaper.d.ts +53 -0
  82. package/dist/text-shaper.d.ts.map +1 -0
  83. package/dist/text-shaper.js +19 -0
  84. package/dist/text-shaper.js.map +1 -0
  85. package/dist/tile-renderer.d.ts +126 -0
  86. package/dist/tile-renderer.d.ts.map +1 -0
  87. package/dist/tile-renderer.js +192 -0
  88. package/dist/tile-renderer.js.map +1 -0
  89. package/dist/worker-render.d.ts +54 -0
  90. package/dist/worker-render.d.ts.map +1 -0
  91. package/dist/worker-render.js +8 -0
  92. package/dist/worker-render.js.map +1 -0
  93. 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
+ }