@nodetool-ai/nodes-utils 0.8.3 → 0.8.4-a24.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.
- package/dist/.nodetool-build-stamp +1 -1
- package/dist/file-watch-match.d.ts +50 -0
- package/dist/file-watch-match.d.ts.map +1 -0
- package/dist/file-watch-match.js +90 -0
- package/dist/file-watch-match.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/model-bytes.d.ts +7 -6
- package/dist/model-bytes.d.ts.map +1 -1
- package/dist/model-bytes.js +17 -44
- package/dist/model-bytes.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
2026-10-
|
|
1
|
+
2026-10-16T07:29:18.966Z
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Shared pattern matching and per-path debounce for file-watch nodes and hosts. */
|
|
2
|
+
/** The filter a watcher applies before turning a raw fs event into an event. */
|
|
3
|
+
export interface FileWatchFilter {
|
|
4
|
+
/** Glob-ish include patterns (e.g. "*.txt"); "*" matches everything. */
|
|
5
|
+
patterns: string[];
|
|
6
|
+
/** Glob-ish patterns to exclude, checked before include patterns. */
|
|
7
|
+
ignorePatterns: string[];
|
|
8
|
+
/** Event types to react to ("created" | "modified" | "deleted" | "moved" | ...). */
|
|
9
|
+
events: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Minimal glob match against a filename: `*` matches any run of characters,
|
|
13
|
+
* `?` matches any single character, everything else is literal. `pattern ===
|
|
14
|
+
* "*"` is short-circuited since it is the common "match everything" case.
|
|
15
|
+
*/
|
|
16
|
+
export declare function matchesFileWatchPattern(filename: string, pattern: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* True when a changed file's basename passes the ignore/include pattern
|
|
19
|
+
* filter: ignore patterns are checked first (an ignored file is never
|
|
20
|
+
* processed even if an include pattern also matches it), then include
|
|
21
|
+
* patterns — no include pattern match means the file is skipped.
|
|
22
|
+
*/
|
|
23
|
+
export declare function shouldProcessFileWatchPath(filePath: string, filter: Pick<FileWatchFilter, "patterns" | "ignorePatterns">): boolean;
|
|
24
|
+
/** True when an event type is one the watcher cares about. */
|
|
25
|
+
export declare function isWatchedFileEvent(eventType: string, events: string[]): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Per-path debounce: tracks the last time each path fired and suppresses a
|
|
28
|
+
* repeat for the same path within `debounceMs`. One instance per watcher (a
|
|
29
|
+
* node run, or one per registration in the host adapter) — state is scoped to
|
|
30
|
+
* that watcher, not shared across paths or watchers.
|
|
31
|
+
*/
|
|
32
|
+
export declare class FileWatchDebouncer {
|
|
33
|
+
private readonly debounceMs;
|
|
34
|
+
private readonly now;
|
|
35
|
+
private readonly lastFiredAt;
|
|
36
|
+
constructor(debounceMs: number, now?: () => number);
|
|
37
|
+
/** Returns true when the event for `filePath` should be suppressed. A path
|
|
38
|
+
* that has never fired is never suppressed — `now` is injectable, so 0 is a
|
|
39
|
+
* time a clock can genuinely read, not a stand-in for "no entry". */
|
|
40
|
+
shouldSuppress(filePath: string): boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Combines the event-type, include/ignore-pattern, and debounce checks in the
|
|
44
|
+
* same order `FileWatchTriggerNode.genProcess()`'s `emitEvent` always applied
|
|
45
|
+
* them: event type first (cheapest), then patterns, then debounce (which has
|
|
46
|
+
* a side effect — it records the fire time — so it must run last and only
|
|
47
|
+
* once the event is otherwise known to matter).
|
|
48
|
+
*/
|
|
49
|
+
export declare function shouldEmitFileWatchEvent(eventType: string, filePath: string, filter: FileWatchFilter, debouncer: FileWatchDebouncer): boolean;
|
|
50
|
+
//# sourceMappingURL=file-watch-match.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watch-match.d.ts","sourceRoot":"","sources":["../src/file-watch-match.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAIpF,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qEAAqE;IACrE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,oFAAoF;IACpF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAgBT;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,gBAAgB,CAAC,GAC3D,OAAO,CAYT;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAET;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,YACmB,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAM,MAAiB,EAC3C;IAEJ;;yEAEqE;IACrE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMxC;CACF;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,kBAAkB,GAC5B,OAAO,CAKT"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/** Shared pattern matching and per-path debounce for file-watch nodes and hosts. */
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Minimal glob match against a filename: `*` matches any run of characters,
|
|
5
|
+
* `?` matches any single character, everything else is literal. `pattern ===
|
|
6
|
+
* "*"` is short-circuited since it is the common "match everything" case.
|
|
7
|
+
*/
|
|
8
|
+
export function matchesFileWatchPattern(filename, pattern) {
|
|
9
|
+
if (pattern === "*")
|
|
10
|
+
return true;
|
|
11
|
+
// Escape every regex metacharacter first, then reinstate the two glob
|
|
12
|
+
// wildcards from their escaped forms. Escaping only "." would leave the
|
|
13
|
+
// rest live: "\d" would match any digit instead of a literal backslash,
|
|
14
|
+
// and an unbalanced "(" would throw at watch time rather than simply
|
|
15
|
+
// failing to match.
|
|
16
|
+
const source = pattern
|
|
17
|
+
.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&")
|
|
18
|
+
.replace(/\\\*/g, ".*")
|
|
19
|
+
.replace(/\\\?/g, ".");
|
|
20
|
+
// "s" because a bare "." skips the four JS line terminators, all of which
|
|
21
|
+
// are legal in a POSIX filename; "u" because it otherwise counts one UTF-16
|
|
22
|
+
// unit, so "?" ate half an emoji. Neither flag can make the compile throw:
|
|
23
|
+
// the escape above already covers every character "u" is strict about.
|
|
24
|
+
return new RegExp(`^${source}$`, "us").test(filename);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* True when a changed file's basename passes the ignore/include pattern
|
|
28
|
+
* filter: ignore patterns are checked first (an ignored file is never
|
|
29
|
+
* processed even if an include pattern also matches it), then include
|
|
30
|
+
* patterns — no include pattern match means the file is skipped.
|
|
31
|
+
*/
|
|
32
|
+
export function shouldProcessFileWatchPath(filePath, filter) {
|
|
33
|
+
const filename = path.basename(filePath);
|
|
34
|
+
for (const pattern of filter.ignorePatterns) {
|
|
35
|
+
if (matchesFileWatchPattern(filename, pattern))
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
for (const pattern of filter.patterns) {
|
|
39
|
+
if (matchesFileWatchPattern(filename, pattern))
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
/** True when an event type is one the watcher cares about. */
|
|
45
|
+
export function isWatchedFileEvent(eventType, events) {
|
|
46
|
+
return events.includes(eventType);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Per-path debounce: tracks the last time each path fired and suppresses a
|
|
50
|
+
* repeat for the same path within `debounceMs`. One instance per watcher (a
|
|
51
|
+
* node run, or one per registration in the host adapter) — state is scoped to
|
|
52
|
+
* that watcher, not shared across paths or watchers.
|
|
53
|
+
*/
|
|
54
|
+
export class FileWatchDebouncer {
|
|
55
|
+
debounceMs;
|
|
56
|
+
now;
|
|
57
|
+
lastFiredAt = new Map();
|
|
58
|
+
constructor(debounceMs, now = Date.now) {
|
|
59
|
+
this.debounceMs = debounceMs;
|
|
60
|
+
this.now = now;
|
|
61
|
+
}
|
|
62
|
+
/** Returns true when the event for `filePath` should be suppressed. A path
|
|
63
|
+
* that has never fired is never suppressed — `now` is injectable, so 0 is a
|
|
64
|
+
* time a clock can genuinely read, not a stand-in for "no entry". */
|
|
65
|
+
shouldSuppress(filePath) {
|
|
66
|
+
const now = this.now();
|
|
67
|
+
const last = this.lastFiredAt.get(filePath);
|
|
68
|
+
if (last !== undefined && now - last < this.debounceMs)
|
|
69
|
+
return true;
|
|
70
|
+
this.lastFiredAt.set(filePath, now);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Combines the event-type, include/ignore-pattern, and debounce checks in the
|
|
76
|
+
* same order `FileWatchTriggerNode.genProcess()`'s `emitEvent` always applied
|
|
77
|
+
* them: event type first (cheapest), then patterns, then debounce (which has
|
|
78
|
+
* a side effect — it records the fire time — so it must run last and only
|
|
79
|
+
* once the event is otherwise known to matter).
|
|
80
|
+
*/
|
|
81
|
+
export function shouldEmitFileWatchEvent(eventType, filePath, filter, debouncer) {
|
|
82
|
+
if (!isWatchedFileEvent(eventType, filter.events))
|
|
83
|
+
return false;
|
|
84
|
+
if (!shouldProcessFileWatchPath(filePath, filter))
|
|
85
|
+
return false;
|
|
86
|
+
if (debouncer.shouldSuppress(filePath))
|
|
87
|
+
return false;
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=file-watch-match.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watch-match.js","sourceRoot":"","sources":["../src/file-watch-match.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAEpF,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAY7B;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAgB,EAChB,OAAe;IAEf,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACjC,sEAAsE;IACtE,wEAAwE;IACxE,wEAAwE;IACxE,qEAAqE;IACrE,oBAAoB;IACpB,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;SACtC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACzB,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,uEAAuE;IACvE,OAAO,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAgB,EAChB,MAA4D;IAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC5C,IAAI,uBAAuB,CAAC,QAAQ,EAAE,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;IAC/D,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,IAAI,uBAAuB,CAAC,QAAQ,EAAE,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,MAAgB;IAEhB,OAAO,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,kBAAkB;IAIV,UAAU;IACV,GAAG;IAJL,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEzD,YACmB,UAAkB,EAClB,GAAG,GAAiB,IAAI,CAAC,GAAG;0BAD5B,UAAU;mBACV,GAAG;IACnB,CAAC;IAEJ;;yEAEqE;IACrE,cAAc,CAAC,QAAgB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QACpE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAAiB,EACjB,QAAgB,EAChB,MAAuB,EACvB,SAA6B;IAE7B,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,IAAI,CAAC,0BAA0B,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,IAAI,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,4 +26,5 @@ export { resolveModelBytes } from "./model-bytes.js";
|
|
|
26
26
|
export type { ModelBytesRefLike } from "./model-bytes.js";
|
|
27
27
|
export { SAVE_TO_WORKSPACE_TITLE, SAVE_TO_WORKSPACE_DESCRIPTION, VISIBLE_WHEN_NOT_SAVING_TO_WORKSPACE, folderPathOf, resolveSaveFolder, saveFilename, uniqueFilePath, resolveSaveTarget, writeSavedFile } from "./save-target.js";
|
|
28
28
|
export type { SaveFilenameOptions, SaveFolderOptions, SaveTargetOptions, SaveWorkspace } from "./save-target.js";
|
|
29
|
+
export * from "./file-watch-match.js";
|
|
29
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,oCAAoC,EACpC,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACd,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,oCAAoC,EACpC,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -23,4 +23,5 @@ export { renderTemplate, referencedVariables } from "./template.js";
|
|
|
23
23
|
export { base64ToBytes, bytesToBase64 } from "./base64.js";
|
|
24
24
|
export { resolveModelBytes } from "./model-bytes.js";
|
|
25
25
|
export { SAVE_TO_WORKSPACE_TITLE, SAVE_TO_WORKSPACE_DESCRIPTION, VISIBLE_WHEN_NOT_SAVING_TO_WORKSPACE, folderPathOf, resolveSaveFolder, saveFilename, uniqueFilePath, resolveSaveTarget, writeSavedFile } from "./save-target.js";
|
|
26
|
+
export * from "./file-watch-match.js";
|
|
26
27
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,oCAAoC,EACpC,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,WAAW,EACZ,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,oCAAoC,EACpC,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAQ1B,cAAc,uBAAuB,CAAC"}
|
package/dist/model-bytes.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser-safe model-bytes resolution (inline data → storage → uri
|
|
2
|
+
* Browser-safe model-bytes resolution (inline data → asset → storage → uri).
|
|
3
3
|
*
|
|
4
4
|
* Moved here from `packages/video-nodes/src/nodes/model3d/render.ts` so the
|
|
5
|
-
* Blender nodes and `RenderToImage` share it.
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Blender nodes and `RenderToImage` share it. It delegates to the runtime's
|
|
6
|
+
* shared `loadMediaRefBytes`, which resolves `asset://<id>` and asset-id-only
|
|
7
|
+
* refs (the shape the Model 3D constant stores), and keeps one difference: a
|
|
8
|
+
* failed HTTP fetch throws with its status instead of reading as empty bytes.
|
|
9
9
|
*/
|
|
10
10
|
import type { ProcessingContext } from "@nodetool-ai/runtime";
|
|
11
11
|
/**
|
|
@@ -16,7 +16,8 @@ import type { ProcessingContext } from "@nodetool-ai/runtime";
|
|
|
16
16
|
export interface ModelBytesRefLike {
|
|
17
17
|
data?: Uint8Array | string;
|
|
18
18
|
uri?: string;
|
|
19
|
+
asset_id?: string | null;
|
|
19
20
|
}
|
|
20
|
-
/** Browser-safe model-bytes resolution (inline data → storage → uri
|
|
21
|
+
/** Browser-safe model-bytes resolution (inline data → asset → storage → uri). */
|
|
21
22
|
export declare function resolveModelBytes(model: ModelBytesRefLike | null | undefined, context?: ProcessingContext): Promise<Uint8Array>;
|
|
22
23
|
//# sourceMappingURL=model-bytes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-bytes.d.ts","sourceRoot":"","sources":["../src/model-bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"model-bytes.d.ts","sourceRoot":"","sources":["../src/model-bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,iFAAiF;AACjF,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EAC3C,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAkBrB"}
|
package/dist/model-bytes.js
CHANGED
|
@@ -1,54 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser-safe model-bytes resolution (inline data → storage → uri
|
|
2
|
+
* Browser-safe model-bytes resolution (inline data → asset → storage → uri).
|
|
3
3
|
*
|
|
4
4
|
* Moved here from `packages/video-nodes/src/nodes/model3d/render.ts` so the
|
|
5
|
-
* Blender nodes and `RenderToImage` share it.
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Blender nodes and `RenderToImage` share it. It delegates to the runtime's
|
|
6
|
+
* shared `loadMediaRefBytes`, which resolves `asset://<id>` and asset-id-only
|
|
7
|
+
* refs (the shape the Model 3D constant stores), and keeps one difference: a
|
|
8
|
+
* failed HTTP fetch throws with its status instead of reading as empty bytes.
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
import { fetchExternalMedia } from "@nodetool-ai/runtime";
|
|
13
|
-
import { base64ToBytes } from "./base64.js";
|
|
14
|
-
/** Browser-safe model-bytes resolution (inline data → storage → uri fetch). */
|
|
10
|
+
import { fetchExternalMedia, loadMediaRefBytes } from "@nodetool-ai/runtime";
|
|
11
|
+
/** Browser-safe model-bytes resolution (inline data → asset → storage → uri). */
|
|
15
12
|
export async function resolveModelBytes(model, context) {
|
|
16
13
|
if (model === null || model === undefined)
|
|
17
14
|
return new Uint8Array();
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (uri === "")
|
|
27
|
-
return new Uint8Array();
|
|
28
|
-
if (uri.startsWith("data:")) {
|
|
29
|
-
const comma = uri.indexOf(",");
|
|
30
|
-
if (comma === -1)
|
|
31
|
-
throw new Error(`Malformed data URI: ${uri.slice(0, 32)}…`);
|
|
32
|
-
return base64ToBytes(uri.slice(comma + 1));
|
|
33
|
-
}
|
|
34
|
-
if (context?.storage) {
|
|
35
|
-
const stored = await context.storage.retrieve(uri);
|
|
36
|
-
if (stored && stored.length > 0)
|
|
37
|
-
return new Uint8Array(stored);
|
|
38
|
-
}
|
|
39
|
-
if (uri.startsWith("file://") && IS_NODE) {
|
|
40
|
-
const { readFile } = await import("node:fs/promises");
|
|
41
|
-
const { fileURLToPath } = await import("node:url");
|
|
42
|
-
return new Uint8Array(await readFile(fileURLToPath(uri)));
|
|
43
|
-
}
|
|
44
|
-
if (uri.startsWith("http://") || uri.startsWith("https://")) {
|
|
45
|
-
// Caller-supplied media uri — the media-ref egress policy decides.
|
|
46
|
-
const res = await fetchExternalMedia(uri);
|
|
47
|
-
if (!res.ok) {
|
|
48
|
-
throw new Error(`Failed to fetch model (${res.status}): ${uri}`);
|
|
15
|
+
const bytes = await loadMediaRefBytes({ data: model.data, uri: model.uri, asset_id: model.asset_id, type: "model3d" }, context, {
|
|
16
|
+
fetchHttp: async (uri) => {
|
|
17
|
+
// Caller-supplied media uri — the media-ref egress policy decides.
|
|
18
|
+
const res = await fetchExternalMedia(uri);
|
|
19
|
+
if (!res.ok) {
|
|
20
|
+
throw new Error(`Failed to fetch model (${res.status}): ${uri}`);
|
|
21
|
+
}
|
|
22
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
49
23
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return new Uint8Array();
|
|
24
|
+
});
|
|
25
|
+
return bytes ?? new Uint8Array();
|
|
53
26
|
}
|
|
54
27
|
//# sourceMappingURL=model-bytes.js.map
|
package/dist/model-bytes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-bytes.js","sourceRoot":"","sources":["../src/model-bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"model-bytes.js","sourceRoot":"","sources":["../src/model-bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAc7E,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAA2C,EAC3C,OAA2B;IAE3B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,UAAU,EAAE,CAAC;IAEnE,MAAM,KAAK,GAAG,MAAM,iBAAiB,CACnC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAC/E,OAAO,EACP;QACE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACvB,mEAAmE;YACnE,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC;YACnE,CAAC;YACD,OAAO,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,CAAC;KACF,CACF,CAAC;IACF,OAAO,KAAK,IAAI,IAAI,UAAU,EAAE,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodetool-ai/nodes-utils",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4-a24.1",
|
|
4
4
|
"description": "Shared helpers for node packages: platform tags and lazy Node-only module loaders",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"lint": "node ../../scripts/run-tsc.mjs --noEmit"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@nodetool-ai/config": "0.8.
|
|
19
|
-
"@nodetool-ai/node-sdk": "0.8.
|
|
20
|
-
"@nodetool-ai/protocol": "0.8.
|
|
21
|
-
"@nodetool-ai/runtime": "0.8.
|
|
18
|
+
"@nodetool-ai/config": "0.8.4-a24.1",
|
|
19
|
+
"@nodetool-ai/node-sdk": "0.8.4-a24.1",
|
|
20
|
+
"@nodetool-ai/protocol": "0.8.4-a24.1",
|
|
21
|
+
"@nodetool-ai/runtime": "0.8.4-a24.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^22.0.0",
|