@neta-art/cohub 11.3.0 → 11.3.1

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.
@@ -2,11 +2,11 @@ import { buildBoardScene } from "../model/scene.js";
2
2
  import { resolveBoardAnimationCamera } from "../model/sampling.js";
3
3
  import { normalizeBoardDocument, planBoardExport } from "../model/export-plan.js";
4
4
  import { parseBoardCssColor } from "../render/css-color.js";
5
+ import { ensureBoardTextMeasurement } from "../render/text-measurement.js";
5
6
  import { defaultBoardPalette } from "../render/palette.js";
6
7
  import { createBoardRenderSampler } from "../render/sampling.js";
7
- import { ensureBoardTextMeasurement } from "../render/text-measurement.js";
8
8
  import { createBoardExportScene } from "./scene.js";
9
- import { Rectangle } from "pixi.js";
9
+ import { Rectangle, RendererType } from "pixi.js";
10
10
  //#region src/board/export/index.ts
11
11
  function resolveBackground(background, palette, document, colorScheme) {
12
12
  if (background === "transparent") return null;
@@ -85,13 +85,24 @@ function renderBoardExport(renderer, input, options = {}) {
85
85
  backgroundImage: options.backgroundImage
86
86
  });
87
87
  try {
88
- const canvas = renderer.extract.canvas({
88
+ const texture = renderer.textureGenerator.generateTexture({
89
89
  target: exportScene.root,
90
90
  frame: new Rectangle(0, 0, plan.width, plan.height),
91
91
  resolution: 1,
92
92
  antialias: true,
93
93
  clearColor: options.background === "transparent" ? void 0 : palette.bg
94
94
  });
95
+ let canvas;
96
+ const surface = renderer.type === RendererType.CANVAS ? texture.source.resource : void 0;
97
+ try {
98
+ canvas = renderer.texture.generateCanvas(texture);
99
+ } finally {
100
+ texture.destroy(true);
101
+ if (surface) {
102
+ surface.width = 1;
103
+ surface.height = 1;
104
+ }
105
+ }
95
106
  const warnings = [];
96
107
  if (plan.clamped) warnings.push({
97
108
  kind: "scale-clamped",
@@ -0,0 +1,13 @@
1
+ //#region src/board/export/node/fonts.d.ts
2
+ type BoardNodeFont = {
3
+ path: string;
4
+ family?: string;
5
+ };
6
+ type BoardFontRegistry = {
7
+ registerFromPath(path: string, family?: string): unknown;
8
+ has(family: string): boolean;
9
+ setAlias?: (family: string, alias: string) => boolean;
10
+ };
11
+ declare function initializeBoardFonts(registry: BoardFontRegistry, fonts: readonly BoardNodeFont[]): void;
12
+ //#endregion
13
+ export { BoardFontRegistry, BoardNodeFont, initializeBoardFonts };
@@ -0,0 +1,44 @@
1
+ //#region src/board/export/node/fonts.ts
2
+ function initializeBoardFonts(registry, fonts) {
3
+ for (const font of fonts) registry.registerFromPath(font.path, font.family);
4
+ if (!registry.setAlias) return;
5
+ for (const [alias, candidates] of Object.entries({
6
+ "system-ui": [
7
+ "Noto Sans",
8
+ "DejaVu Sans",
9
+ "Liberation Sans",
10
+ "FreeSans",
11
+ "Helvetica Neue",
12
+ "Arial",
13
+ "Segoe UI"
14
+ ],
15
+ "sans-serif": [
16
+ "Geist",
17
+ "Noto Sans",
18
+ "DejaVu Sans",
19
+ "Liberation Sans",
20
+ "FreeSans",
21
+ "Arial"
22
+ ],
23
+ serif: [
24
+ "Noto Serif",
25
+ "DejaVu Serif",
26
+ "Liberation Serif",
27
+ "FreeSerif",
28
+ "Times New Roman"
29
+ ],
30
+ monospace: [
31
+ "Geist Mono",
32
+ "DejaVu Sans Mono",
33
+ "Liberation Mono",
34
+ "FreeMono",
35
+ "Courier New"
36
+ ]
37
+ })) {
38
+ if (registry.has(alias)) continue;
39
+ const family = candidates.find((name) => registry.has(name));
40
+ if (family) registry.setAlias(family, alias);
41
+ }
42
+ }
43
+ //#endregion
44
+ export { initializeBoardFonts };
@@ -2,21 +2,14 @@ import { BoardDocument } from "../../../protocol/dist/board-model.js";
2
2
  import "../../../protocol/dist/index.js";
3
3
  import { BoardScriptHost } from "../../render/renderers/board-renderer-registry.js";
4
4
  import { BoardExportOptions, BoardExportResult } from "../index.js";
5
+ import { BoardFontRegistry, BoardNodeFont } from "./fonts.js";
5
6
  import { createNodeBoardScriptHost } from "./scripts.js";
6
7
  import { Renderer } from "pixi.js";
7
8
  //#region src/board/export/node/index.d.ts
8
9
  type NodeCanvasModule = {
9
10
  createCanvas: (width: number, height: number) => unknown;
10
11
  Image: new () => unknown;
11
- GlobalFonts: {
12
- registerFromPath: (path: string, name?: string) => unknown;
13
- has: (name: string) => boolean;
14
- setAlias?: (fontName: string, alias: string) => boolean;
15
- };
16
- };
17
- type BoardNodeFont = {
18
- path: string;
19
- family?: string;
12
+ GlobalFonts: BoardFontRegistry;
20
13
  };
21
14
  type BoardNodeRendererOptions = {
22
15
  fonts?: BoardNodeFont[];
@@ -29,6 +22,7 @@ type BoardNodeTexture = {
29
22
  type BoardNodeRenderer = {
30
23
  renderer: Renderer;
31
24
  canvasModule: NodeCanvasModule;
25
+ fonts?: readonly BoardNodeFont[];
32
26
  decodeImage: (bytes: Uint8Array, mimeType?: string) => Promise<BoardNodeTexture>;
33
27
  destroy: () => void;
34
28
  };
@@ -53,4 +47,4 @@ type BoardNodeExportResult = Omit<BoardExportResult, "canvas"> & {
53
47
  declare function boardImageMimeType(format: BoardNodeExportFormat): string;
54
48
  declare function exportBoardImageBytes(renderer: BoardNodeRenderer, document: BoardDocument, options?: BoardNodeExportOptions): BoardNodeExportResult | null;
55
49
  //#endregion
56
- export { BoardNodeExportFormat, BoardNodeExportOptions, BoardNodeExportResult, BoardNodeFont, BoardNodeRenderer, BoardNodeRendererOptions, BoardNodeTexture, NodeCanvasModule, boardImageMimeType, createNodeBoardRenderer, createNodeBoardScriptHost, exportBoardImageBytes };
50
+ export { BoardNodeExportFormat, BoardNodeExportOptions, BoardNodeExportResult, type BoardNodeFont, BoardNodeRenderer, BoardNodeRendererOptions, BoardNodeTexture, NodeCanvasModule, boardImageMimeType, createNodeBoardRenderer, createNodeBoardScriptHost, exportBoardImageBytes };
@@ -1,23 +1,10 @@
1
1
  import "../../../protocol/dist/board-constants.js";
2
2
  import { installBoardTextMeasurement } from "../../render/text-measurement.js";
3
3
  import { renderBoardExport } from "../index.js";
4
+ import { initializeBoardFonts } from "./fonts.js";
4
5
  import { createNodeBoardScriptHost } from "./scripts.js";
5
6
  import { CanvasGraphicsContextSystem, CanvasGraphicsPipe, CanvasRenderer, CanvasRendererTextSystem, CanvasTextPipe, CanvasTextSystem, DOMAdapter, GraphicsContextSystem, GraphicsPipe, ImageSource, Texture, extensions } from "pixi.js";
6
7
  //#region src/board/export/node/index.ts
7
- const SYSTEM_UI_FAMILIES = [
8
- "Noto Sans",
9
- "DejaVu Sans",
10
- "Liberation Sans",
11
- "FreeSans",
12
- "Helvetica Neue",
13
- "Arial",
14
- "Segoe UI"
15
- ];
16
- function aliasSystemUi(fonts) {
17
- if (!fonts.setAlias || fonts.has("system-ui")) return;
18
- const family = SYSTEM_UI_FAMILIES.find((name) => fonts.has(name));
19
- if (family) fonts.setAlias(family, "system-ui");
20
- }
21
8
  const WEBGL_PROBE_STUB = {
22
9
  getShaderPrecisionFormat: () => ({
23
10
  precision: 1,
@@ -64,8 +51,11 @@ function installAnimationFrameShim() {
64
51
  async function createNodeBoardRenderer(options = {}) {
65
52
  const canvasModule = options.canvasModule ?? await loadCanvasModule();
66
53
  extensions.add(CanvasGraphicsPipe, GraphicsPipe, CanvasGraphicsContextSystem, GraphicsContextSystem, CanvasRendererTextSystem, CanvasTextSystem, CanvasTextPipe);
67
- for (const font of options.fonts ?? []) canvasModule.GlobalFonts.registerFromPath(font.path, font.family ?? "Geist");
68
- aliasSystemUi(canvasModule.GlobalFonts);
54
+ const fonts = (options.fonts ?? []).map((font) => ({
55
+ ...font,
56
+ family: font.family ?? "Geist"
57
+ }));
58
+ initializeBoardFonts(canvasModule.GlobalFonts, fonts);
69
59
  function createCanvas(width = 1, height = 1) {
70
60
  const canvas = canvasModule.createCanvas(Math.max(1, Math.ceil(width)), Math.max(1, Math.ceil(height)));
71
61
  const nativeGetContext = canvas.getContext.bind(canvas);
@@ -102,14 +92,16 @@ async function createNodeBoardRenderer(options = {}) {
102
92
  return {
103
93
  renderer,
104
94
  canvasModule,
105
- decodeImage: async (bytes, mimeType = "image/png") => {
95
+ fonts,
96
+ decodeImage: async (bytes) => {
106
97
  const image = new canvasModule.Image();
107
- const base64 = Buffer.from(bytes).toString("base64");
108
98
  await new Promise((resolve, reject) => {
109
99
  image.onload = () => resolve();
110
100
  image.onerror = (error) => reject(error);
111
- image.src = `data:${mimeType};base64,${base64}`;
101
+ image.src = bytes;
112
102
  });
103
+ image.onload = void 0;
104
+ image.onerror = void 0;
113
105
  return new Texture({ source: new ImageSource({
114
106
  resource: image,
115
107
  width: image.width,
@@ -146,7 +138,7 @@ function exportBoardImageBytes(renderer, document, options = {}) {
146
138
  try {
147
139
  const bytes = format === "png" ? canvas.toBuffer(MIME.png) : canvas.toBuffer(MIME[format], Math.round(quality * 100));
148
140
  return {
149
- bytes: new Uint8Array(bytes),
141
+ bytes: new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength),
150
142
  plan: result.plan,
151
143
  warnings: result.warnings,
152
144
  format
@@ -4,6 +4,7 @@ import { BoardNodeRenderer } from "./index.js";
4
4
  //#region src/board/export/node/scripts.d.ts
5
5
  type BoardNodeScriptOptions = {
6
6
  readModule(src: string): Promise<string>;
7
+ concurrency?: number;
7
8
  timeoutMs?: number;
8
9
  readTimeoutMs?: number;
9
10
  };
@@ -2,13 +2,15 @@ import { boardScriptScope, composeBoardScriptItems } from "../../model/script-sc
2
2
  import { buildBoardScene } from "../../model/scene.js";
3
3
  import { createBoardScriptModuleReader, loadBoardScriptSources } from "../../../protocol/dist/board-script-modules.js";
4
4
  import { createScriptRuntime } from "../../render/script-runtime.js";
5
+ import { initializeBoardFonts } from "./fonts.js";
5
6
  import { Worker } from "node:worker_threads";
6
7
  import { fileURLToPath } from "node:url";
7
8
  //#region src/board/export/node/scripts.ts
8
9
  const WORKER = `
9
10
  const {parentPort, workerData} = require('node:worker_threads');
10
11
  const {createContext, Script, SourceTextModule} = require('node:vm');
11
- const {createCanvas} = require(workerData.canvasModule);
12
+ const {createCanvas, GlobalFonts} = require(workerData.canvasModule);
13
+ (${initializeBoardFonts.toString()})(GlobalFonts, workerData.fonts);
12
14
  const instances = new Map();
13
15
  const graphs = new Map();
14
16
  const update = new Script('__runtime.update(JSON.parse(__inputJson)); __runtime.step(__time)');
@@ -17,7 +19,10 @@ const output = new Script('JSON.stringify(__runtime.output())');
17
19
  const dispose = new Script('__runtime.destroy()');
18
20
  function release(id) {
19
21
  const entry=instances.get(id);instances.delete(id);
20
- if(entry) {try {dispose.runInContext(entry.context,{timeout:workerData.timeout});} catch {}}
22
+ if(entry) {
23
+ try {dispose.runInContext(entry.context,{timeout:workerData.timeout});} catch {}
24
+ if(entry.canvas) {entry.canvas.width=1;entry.canvas.height=1;}
25
+ }
21
26
  }
22
27
  async function create(data) {
23
28
  const context = createContext({console:{log(){},warn(){},error(){}},structuredClone},{codeGeneration:{strings:false,wasm:false}});
@@ -67,22 +72,29 @@ parentPort.on('message',async data=>{
67
72
  const width=Math.max(1,Math.round(data.input.width*data.scale));
68
73
  const height=Math.max(1,Math.round(data.input.height*data.scale));
69
74
  const canvas=entry.canvas??=createCanvas(width,height);
70
- canvas.width=width;canvas.height=height;
71
- const drawing=canvas.getContext('2d');drawing.scale(data.scale,data.scale);
72
- context.__drawing=drawing;draw.runInContext(context,{timeout:workerData.timeout});
73
- png=canvas.toBuffer('image/png');delete context.__drawing;
75
+ if(canvas.width!==width || canvas.height!==height) {canvas.width=width;canvas.height=height;}
76
+ const drawing=canvas.getContext('2d');drawing.reset();drawing.scale(data.scale,data.scale);
77
+ context.__drawing=drawing;
78
+ try {
79
+ draw.runInContext(context,{timeout:workerData.timeout});
80
+ png=canvas.toBuffer('image/png');
81
+ } finally {
82
+ delete context.__drawing;canvas.width=1;canvas.height=1;
83
+ }
74
84
  }
75
85
  parentPort.postMessage({png,output:JSON.parse(output.runInContext(context,{timeout:workerData.timeout}))});
76
- } catch(error) { instances.delete(data.input?.id);parentPort.postMessage({error:String(error.stack||error)}); }
86
+ } catch(error) { release(data.input?.id);parentPort.postMessage({error:String(error.stack||error)}); }
77
87
  });
78
88
  `;
79
89
  function createNodeBoardScriptHost(renderer, options) {
90
+ const concurrency = options.concurrency ?? 4;
91
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > 4) throw new Error("Script concurrency must be an integer between 1 and 4.");
80
92
  const textures = /* @__PURE__ */ new Map();
81
93
  const outputs = /* @__PURE__ */ new Map();
82
94
  const errors = /* @__PURE__ */ new Map();
83
95
  const sources = /* @__PURE__ */ new Map();
84
96
  const modules = createBoardScriptModuleReader(options.readModule, options.readTimeoutMs);
85
- const lanes = Array.from({ length: 4 }, () => ({
97
+ const lanes = Array.from({ length: concurrency }, () => ({
86
98
  worker: null,
87
99
  tail: Promise.resolve(),
88
100
  graphs: /* @__PURE__ */ new Set()
@@ -123,6 +135,7 @@ function createNodeBoardScriptHost(renderer, options) {
123
135
  workerData: {
124
136
  runtime: createScriptRuntime.toString(),
125
137
  timeout,
138
+ fonts: renderer.fonts ?? [],
126
139
  canvasModule: fileURLToPath(import.meta.resolve("@napi-rs/canvas"))
127
140
  }
128
141
  });
@@ -1,7 +1,7 @@
1
1
  import { buildFallbackShapeColors } from "../model/palette.js";
2
2
  import { imageAssetKey } from "../model/image-key.js";
3
- import { defaultBoardPalette } from "../render/palette.js";
4
3
  import { clippingAncestor, isClippingFrame, syncClipGroup } from "../render/clip.js";
4
+ import { defaultBoardPalette } from "../render/palette.js";
5
5
  import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
6
6
  import { resolveBoardRenderStyle } from "../render/style.js";
7
7
  import { Container, Graphics, Sprite, TilingSprite } from "pixi.js";
@@ -1,5 +1,7 @@
1
1
  import { BoardTextItem } from "../../protocol/dist/board-model.js";
2
+ import { BoardFrame } from "../../protocol/dist/board-layout.js";
2
3
  import "../../protocol/dist/index.js";
4
+ import { Rect } from "../model/geometry.js";
3
5
  import { BoardScene } from "../model/scene.js";
4
6
  //#region src/board/render/diagnostics.d.ts
5
7
  type BoardRenderDiagnostic = {
@@ -15,6 +17,22 @@ declare function measureBoardText(props: BoardTextItem["props"]): {
15
17
  lineHeight: number;
16
18
  missingCharacters: string;
17
19
  };
18
- declare function inspectBoardScene(scene: BoardScene, limit?: number): BoardRenderDiagnostic[];
20
+ declare function inspectBoardItems(scene: BoardScene, ids?: ReadonlySet<string>): {
21
+ diagnostics: BoardRenderDiagnostic[];
22
+ items: {
23
+ id: string;
24
+ bounds: BoardFrame;
25
+ worldBounds: Rect;
26
+ opacity: number;
27
+ text?: {
28
+ width: number;
29
+ height: number;
30
+ lines: string[];
31
+ lineHeight: number;
32
+ missingCharacters: string;
33
+ } | undefined;
34
+ }[];
35
+ };
36
+ declare function inspectBoardScene(scene: BoardScene, limit?: number, ids?: ReadonlySet<string>): BoardRenderDiagnostic[];
19
37
  //#endregion
20
- export { BoardRenderDiagnostic, inspectBoardScene, measureBoardText };
38
+ export { BoardRenderDiagnostic, inspectBoardItems, inspectBoardScene, measureBoardText };
@@ -46,12 +46,24 @@ function measureBoardText(props) {
46
46
  missingCharacters: characters
47
47
  };
48
48
  }
49
- function inspectBoardScene(scene, limit = 100) {
49
+ function inspectBoardItems(scene, ids) {
50
+ return {
51
+ diagnostics: inspectBoardScene(scene, 100, ids),
52
+ items: scene.items.filter((item) => !ids || ids.has(item.id)).map((item) => ({
53
+ id: item.id,
54
+ bounds: item.frame,
55
+ worldBounds: itemBounds(item.frame),
56
+ opacity: scene.opacity(item.id),
57
+ ...item.type === "text" ? { text: measureBoardText(item.props) } : {}
58
+ }))
59
+ };
60
+ }
61
+ function inspectBoardScene(scene, limit = 100, ids) {
50
62
  ensureBoardTextMeasurement();
51
63
  const diagnostics = [];
52
64
  const texts = scene.items.filter((item) => item.type === "text" && scene.opacity(item.id) > .01);
53
65
  const push = (entry) => {
54
- if (diagnostics.length < limit) diagnostics.push(entry);
66
+ if (diagnostics.length < limit && (!ids || ids.has(entry.item) || Boolean(entry.related && ids.has(entry.related)))) diagnostics.push(entry);
55
67
  };
56
68
  for (const item of scene.items) {
57
69
  if (diagnostics.length >= limit) break;
@@ -63,7 +75,7 @@ function inspectBoardScene(scene, limit = 100) {
63
75
  let glyphBudget = 256;
64
76
  for (const item of texts) {
65
77
  if (diagnostics.length >= limit || item.type !== "text") break;
66
- if (glyphBudget-- > 0) {
78
+ if ((!ids || ids.has(item.id)) && glyphBudget-- > 0) {
67
79
  const measured = measureBoardText(item.props);
68
80
  if (measured.missingCharacters) push({
69
81
  code: "glyph-unavailable",
@@ -102,6 +114,7 @@ function inspectBoardScene(scene, limit = 100) {
102
114
  const b = sorted[j];
103
115
  if (!b) continue;
104
116
  if (b.rect.x >= a.rect.x + a.rect.width) break;
117
+ if (ids && !ids.has(a.item.id) && !ids.has(b.item.id)) continue;
105
118
  if (++comparisons > 1e4) return diagnostics;
106
119
  if (a.item.parent === b.item.parent && rectsIntersect(a.rect, b.rect)) push({
107
120
  code: "text-overlap",
@@ -114,4 +127,4 @@ function inspectBoardScene(scene, limit = 100) {
114
127
  return diagnostics;
115
128
  }
116
129
  //#endregion
117
- export { inspectBoardScene, measureBoardText };
130
+ export { inspectBoardItems, inspectBoardScene, measureBoardText };
@@ -1,7 +1,7 @@
1
1
  import { BoardRenderStyle, BoardSelectionStyle, BoardShadowStyle, defaultBoardRenderStyle, resolveBoardRenderStyle } from "./style.js";
2
2
  import { BoardCardRenderer, BoardCardRendererResolver, BoardRenderContext, BoardRenderLabels, BoardRenderPalette, BoardScriptHost, DEFAULT_BOARD_RENDER_LABELS, createBoardCardRendererResolver, getBoardCardRenderer } from "./renderers/board-renderer-registry.js";
3
3
  import { createBoardRenderSampler } from "./sampling.js";
4
- import { BoardRenderDiagnostic, inspectBoardScene, measureBoardText } from "./diagnostics.js";
4
+ import { BoardRenderDiagnostic, inspectBoardItems, inspectBoardScene, measureBoardText } from "./diagnostics.js";
5
5
  import { BoardBackgroundContext, createBoardBackground, updateBoardBackground } from "./board-background.js";
6
6
  import { CARD_TAG_SIZE, CardGlyph, CardTag, createCardTag, drawCardGlyph, formatBoardDuration, syncCardTag, zoomCardTag } from "./card-tag.js";
7
7
  import { ClipGroup, clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
@@ -17,4 +17,4 @@ import { ellipsizeWrappedLines, fitLineWithEllipsis, fitTextToLines, fitTextToWi
17
17
  import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
18
18
  import { boardCardDetailed, getBoardResolution, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket } from "./text-resolution.js";
19
19
  import { VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
20
- export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BoardBackgroundContext, BoardCardRenderer, BoardCardRendererResolver, BoardCssPaint, BoardMediaAction, BoardRenderContext, BoardRenderDiagnostic, BoardRenderLabels, BoardRenderPalette, BoardRenderStyle, BoardScriptHost, BoardScriptHostOptions, BoardSelectionStyle, BoardShadowStyle, BrowserBoardScriptHost, CARD_TAG_SIZE, CardElevation, CardGlyph, CardRect, CardSurface, CardTag, ClipGroup, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardDetailed, boardMediaActionAt, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, traceArrowhead, traceCardOutline, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
20
+ export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, BoardBackgroundContext, BoardCardRenderer, BoardCardRendererResolver, BoardCssPaint, BoardMediaAction, BoardRenderContext, BoardRenderDiagnostic, BoardRenderLabels, BoardRenderPalette, BoardRenderStyle, BoardScriptHost, BoardScriptHostOptions, BoardSelectionStyle, BoardShadowStyle, BrowserBoardScriptHost, CARD_TAG_SIZE, CardElevation, CardGlyph, CardRect, CardSurface, CardTag, ClipGroup, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardDetailed, boardMediaActionAt, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, traceArrowhead, traceCardOutline, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
@@ -1,13 +1,13 @@
1
1
  import { parseBoardCssColor, parseBoardCssPaint } from "./css-color.js";
2
- import { defaultBoardPalette, itemAlpha, itemColor } from "./palette.js";
3
- import { createBoardRenderSampler } from "./sampling.js";
4
- import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
5
- import { inspectBoardScene, measureBoardText } from "./diagnostics.js";
6
2
  import { createBoardBackground, updateBoardBackground } from "./board-background.js";
7
3
  import { ellipsizeWrappedLines, fitLineWithEllipsis, fitTextToLines, fitTextToWidth } from "./text-fit.js";
8
4
  import { boardCardDetailed, getBoardResolution, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket } from "./text-resolution.js";
9
5
  import { CARD_TAG_SIZE, createCardTag, drawCardGlyph, formatBoardDuration, syncCardTag, zoomCardTag } from "./card-tag.js";
10
6
  import { clippingAncestor, isClippingFrame, syncClipGroup, traceFrameOutline } from "./clip.js";
7
+ import { BOARD_FONT_STACKS, ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-measurement.js";
8
+ import { inspectBoardItems, inspectBoardScene, measureBoardText } from "./diagnostics.js";
9
+ import { defaultBoardPalette, itemAlpha, itemColor } from "./palette.js";
10
+ import { createBoardRenderSampler } from "./sampling.js";
11
11
  import { dashPattern, endAngle, roundRectPoints, traceArrowhead, tracePolyline, trimPolyline } from "./stroke.js";
12
12
  import { PIXEL_STEP, cardElevation, cardOutlinePoints, cardShadow, containRect, drawCardShadow, drawCardSurface, isBoardCard, traceCardOutline, tracePixelRect } from "./surface.js";
13
13
  import { boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter } from "./media-interaction.js";
@@ -17,4 +17,4 @@ import { createBoardScriptHost } from "./script-host.js";
17
17
  import { prepareBrowserBoardScripts } from "./script-export.js";
18
18
  import { defaultBoardRenderStyle, resolveBoardRenderStyle } from "./style.js";
19
19
  import { VIDEO_THUMBNAIL_MAX_EDGE, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
20
- export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, CARD_TAG_SIZE, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, boardCardDetailed, boardMediaActionAt, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, traceArrowhead, traceCardOutline, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
20
+ export { BOARD_EFFECT_MAX_PARTICLES, BOARD_FONT_STACKS, CARD_TAG_SIZE, DEFAULT_BOARD_RENDER_LABELS, PIXEL_STEP, VIDEO_THUMBNAIL_MAX_EDGE, boardCardDetailed, boardMediaActionAt, cardElevation, cardOutlinePoints, cardShadow, clippingAncestor, containRect, createBoardBackground, createBoardCardRendererResolver, createBoardRenderSampler, createBoardScriptHost, createCardTag, dashPattern, defaultBoardPalette, defaultBoardRenderStyle, drawCardGlyph, drawCardShadow, drawCardSurface, ellipsizeWrappedLines, endAngle, ensureBoardTextMeasurement, fitLineWithEllipsis, fitTextToLines, fitTextToWidth, formatBoardDuration, getBoardCardRenderer, getBoardResolution, inspectBoardItems, inspectBoardScene, installBoardTextMeasurement, isBoardCard, isClippingFrame, itemAlpha, itemColor, loadVideoThumbnailTexture, measureBoardText, mediaPlayBadgeHit, mediaPlayBadgeVisible, mediaPlayKeyCenter, parseBoardCssColor, parseBoardCssPaint, prepareBrowserBoardScripts, resolveBoardRenderStyle, roundRectPoints, syncCardTag, syncClipGroup, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, traceArrowhead, traceCardOutline, traceFrameOutline, tracePixelRect, tracePolyline, trimPolyline, updateBoardBackground, videoTextureNaturalSize, videoThumbnailSize, zoomCardTag };
@@ -1,7 +1,7 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
2
  import { pathPointAt, resolveSceneArrow } from "../../model/arrow-geometry.js";
3
- import { itemAlpha, itemColor } from "../palette.js";
4
3
  import { syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
4
+ import { itemAlpha, itemColor } from "../palette.js";
5
5
  import { dashPattern, endAngle, traceArrowhead, tracePolyline, trimPolyline } from "../stroke.js";
6
6
  import { drawCardSurface } from "../surface.js";
7
7
  import { drawFarStroke } from "./far-plate.js";
@@ -1,8 +1,8 @@
1
1
  import { getMediaResourceTitle } from "../../model/media.js";
2
+ import { drawAudioWaveform } from "../audio-waveform.js";
2
3
  import { fitTextToWidth } from "../text-fit.js";
3
4
  import { boardCardDetailed, syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
4
5
  import { formatBoardDuration } from "../card-tag.js";
5
- import { drawAudioWaveform } from "../audio-waveform.js";
6
6
  import { cardElevation, drawCardSurface } from "../surface.js";
7
7
  import { positionShell } from "./base-card-renderer.js";
8
8
  import { drawFarPlate } from "./far-plate.js";
@@ -1,6 +1,6 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
- import { itemAlpha, itemColor } from "../palette.js";
3
2
  import { syncTextResolution } from "../text-resolution.js";
3
+ import { itemAlpha, itemColor } from "../palette.js";
4
4
  import { dashPattern, roundRectPoints, tracePolyline, trimPolyline } from "../stroke.js";
5
5
  import { createLabel, positionShell } from "./base-card-renderer.js";
6
6
  import { drawFarPlate } from "./far-plate.js";
@@ -1,7 +1,7 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
2
  import { worldPoint } from "../../model/geometry.js";
3
- import { itemAlpha, itemColor } from "../palette.js";
4
3
  import { syncTextResolution, syncTextWrapWidth, textResolutionForZoom } from "../text-resolution.js";
4
+ import { itemAlpha, itemColor } from "../palette.js";
5
5
  import { dashPattern, roundRectPoints, tracePolyline, trimPolyline } from "../stroke.js";
6
6
  import { positionShell } from "./base-card-renderer.js";
7
7
  import { drawFarPlate } from "./far-plate.js";
@@ -1,9 +1,9 @@
1
1
  import { BOARD_FONT_STACK, BOARD_MONO_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
2
  import { featuredTaskArtifact } from "../../../protocol/dist/board-task.js";
3
+ import { drawAudioWaveform } from "../audio-waveform.js";
3
4
  import { fitTextToLines } from "../text-fit.js";
4
5
  import { boardCardDetailed, syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
5
6
  import { createCardTag, formatBoardDuration, syncCardTag, zoomCardTag } from "../card-tag.js";
6
- import { drawAudioWaveform } from "../audio-waveform.js";
7
7
  import { cardElevation, containRect, drawCardSurface, traceCardOutline } from "../surface.js";
8
8
  import { positionShell } from "./base-card-renderer.js";
9
9
  import { drawFarPlate } from "./far-plate.js";
@@ -1,8 +1,8 @@
1
1
  import { layoutBoardText } from "../../../protocol/dist/board-layout.js";
2
2
  import { boardFontFamily } from "../../model/text-metrics.js";
3
- import { itemAlpha, itemColor } from "../palette.js";
4
- import { BOARD_FONT_STACKS } from "../text-measurement.js";
5
3
  import { syncTextResolution, textResolutionForZoom } from "../text-resolution.js";
4
+ import { BOARD_FONT_STACKS } from "../text-measurement.js";
5
+ import { itemAlpha, itemColor } from "../palette.js";
6
6
  import { positionShell } from "./base-card-renderer.js";
7
7
  import { drawFarPlate } from "./far-plate.js";
8
8
  import { Container, Graphics, Text } from "pixi.js";
@@ -8,15 +8,15 @@ import { resolveSceneArrow } from "../model/arrow-geometry.js";
8
8
  import { buildFallbackShapeColors, pickBoardColor, resolveItemColor } from "../model/palette.js";
9
9
  import { isCreationBoardTool } from "../editor/tool.js";
10
10
  import { resizeCursorForHandle } from "../editor/selection-transform.js";
11
+ import { createBoardPlayer } from "../player/index.js";
12
+ import { createBoardScriptObservers } from "../model/script-observers.js";
11
13
  import { parseBoardCssColor } from "../render/css-color.js";
12
- import { defaultBoardPalette, itemAlpha } from "../render/palette.js";
13
14
  import { createBoardBackground, updateBoardBackground } from "../render/board-background.js";
14
15
  import { getBoardResolution, textZoomBucket } from "../render/text-resolution.js";
16
+ import { defaultBoardPalette, itemAlpha } from "../render/palette.js";
15
17
  import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
16
18
  import { createBoardScriptHost } from "../render/script-host.js";
17
19
  import { defaultBoardRenderStyle } from "../render/style.js";
18
- import { createBoardPlayer } from "../player/index.js";
19
- import { createBoardScriptObservers } from "../model/script-observers.js";
20
20
  import { toBoardPointerEvent } from "./pointer.js";
21
21
  import { createBoardScene } from "./scene.js";
22
22
  import { scheduleBoardMaintenance } from "./maintenance.js";
@@ -5606,6 +5606,7 @@ declare const fileWatcherStatusSchema: z.ZodObject<{
5606
5606
  fsevents: "fsevents";
5607
5607
  fsnotify: "fsnotify";
5608
5608
  none: "none";
5609
+ readdcw: "readdcw";
5609
5610
  scan: "scan";
5610
5611
  }>;
5611
5612
  state: z.ZodEnum<{
package/dist/index.js CHANGED
@@ -3336,6 +3336,7 @@ const runtimeTraceContextSchema = z.object({
3336
3336
  z.object({
3337
3337
  backend: z.enum([
3338
3338
  "fsevents",
3339
+ "readdcw",
3339
3340
  "fsnotify",
3340
3341
  "scan",
3341
3342
  "none"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub",
3
- "version": "11.3.0",
3
+ "version": "11.3.1",
4
4
  "description": "Cohub SDK for spaces, sessions, boards, and realtime agent collaboration.",
5
5
  "license": "Apache-2.0",
6
6
  "private": false,