@volter/blender-engine 0.1.33 → 0.1.35

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.
@@ -99,7 +99,7 @@ interface WaliProgram {
99
99
  }
100
100
 
101
101
  interface RuntimeIndex {
102
- files: { path: string; size: number; mode: number }[];
102
+ files: { path: string; size: number; mode: number; sha256: string }[];
103
103
  }
104
104
 
105
105
  /** The substrate, as modules this editor serves. `@vite-ignore` because the
@@ -261,7 +261,8 @@ async function installedRuntime(
261
261
  const text = await indexAnswer.text();
262
262
  const index = JSON.parse(text) as RuntimeIndex;
263
263
  // The tree's version is its index: the same files at the same sizes and modes, in the same order,
264
- // and its newest file's time (`runtimeTag`'s validator), so a file rebuilt at the same size is a new version.
264
+ // each with its content's SHA-256, so a file rebuilt with different bytes is a new version
265
+ // whatever its size and time.
265
266
  const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text)));
266
267
  const tag = [...digest.slice(0, 12)].map((byte) => byte.toString(16).padStart(2, '0')).join('');
267
268
  const projectId = `${RUNTIME_STORE_FAMILY}${tag}`;
@@ -136,6 +136,9 @@ export interface BlenderCallMetrics {
136
136
  export class BlenderRuntime {
137
137
  readonly #worker: Worker;
138
138
  readonly #options: BlenderRuntimeOptions;
139
+ /** Blender's own last output lines, which are what says why it died when it dies: they reach
140
+ * the page as ordinary output, so the failure below carries them. */
141
+ readonly #lastLines: string[] = [];
139
142
  readonly #pending = new Map<
140
143
  number,
141
144
  { resolve: (value: unknown) => void; reject: (error: Error) => void }
@@ -180,8 +183,12 @@ export class BlenderRuntime {
180
183
  const thrown = event.error as Error | undefined;
181
184
  const where = event.filename ? ` at ${event.filename}:${event.lineno}:${event.colno}` : '';
182
185
  const said = thrown?.stack ?? thrown?.message ?? event.message;
186
+ // AND BLENDER'S OWN LAST WORDS: a thread that dies throws whatever it threw, often not an
187
+ // Error ("Uncaught [object Object]"), while the reason (an allocation that failed, the file
188
+ // it was reading) is the last thing Blender printed.
189
+ const last = this.#lastLines.length > 0 ? `\nBlender's last output:\n${this.#lastLines.join('\n')}` : '';
183
190
  const error = new Error(
184
- `Blender worker failed: ${said || 'the worker script did not load'}${where}`,
191
+ `Blender worker failed: ${said || 'the worker script did not load'}${where}${last}`,
185
192
  );
186
193
  // The page console is the editor's ledger (`installEditorConsoleReporting`
187
194
  // captures it, source-blind), and this package may import nothing of the
@@ -551,6 +558,8 @@ export class BlenderRuntime {
551
558
  return;
552
559
  }
553
560
  if (reply.op === 'log') {
561
+ this.#lastLines.push(reply.text);
562
+ if (this.#lastLines.length > 12) this.#lastLines.shift();
554
563
  this.#options.log?.(reply.level, reply.text);
555
564
  return;
556
565
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@volter/blender-engine",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "GPL-3.0-or-later",
5
- "version": "0.1.33",
5
+ "version": "0.1.35",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },