novaapp-sdk 1.4.0 → 1.4.2
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/bin/nova.mjs +23 -0
- package/dist/chunk-53M2BTB5.mjs +26 -0
- package/dist/chunk-LMORGVJR.mjs +124 -0
- package/dist/cli/index.d.mts +6 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +871 -0
- package/dist/cli/index.mjs +716 -0
- package/dist/client-DbKa6yJo.d.mts +4244 -0
- package/dist/client-DbKa6yJo.d.ts +4244 -0
- package/dist/devtools/index.d.mts +94 -0
- package/dist/devtools/index.d.ts +94 -0
- package/dist/devtools/index.js +160 -0
- package/dist/devtools/index.mjs +7 -0
- package/dist/index.d.mts +6802 -2834
- package/dist/index.d.ts +6802 -2834
- package/dist/index.js +11200 -1342
- package/dist/index.mjs +11109 -1342
- package/dist/testing/index.d.mts +689 -0
- package/dist/testing/index.d.ts +689 -0
- package/dist/testing/index.js +849 -0
- package/dist/testing/index.mjs +820 -0
- package/package.json +17 -3
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module devtools/HotLoader
|
|
5
|
+
*
|
|
6
|
+
* File-watcher utility for development mode (`nova dev`).
|
|
7
|
+
*
|
|
8
|
+
* Uses Node's built-in `fs.watch` — **no external dependencies**.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { HotLoader } from 'novaapp-sdk/devtools'
|
|
13
|
+
*
|
|
14
|
+
* const loader = new HotLoader('./src', { debounce: 300 })
|
|
15
|
+
*
|
|
16
|
+
* loader.on('reload', path => console.log(`Reloading because ${path} changed`))
|
|
17
|
+
* loader.start()
|
|
18
|
+
*
|
|
19
|
+
* // When a module changes, re-run your setup:
|
|
20
|
+
* loader.restart(async () => {
|
|
21
|
+
* await client.disconnect()
|
|
22
|
+
* // ...rebuild / re-require...
|
|
23
|
+
* await client.connect()
|
|
24
|
+
* })
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
interface HotLoaderOptions {
|
|
29
|
+
/** Debounce window in milliseconds before a `reload` event fires. Default: 250ms. */
|
|
30
|
+
debounce?: number;
|
|
31
|
+
/** Extensions to watch. Default: `['.ts', '.js', '.mjs', '.cjs', '.json']`. */
|
|
32
|
+
extensions?: string[];
|
|
33
|
+
/** Whether to watch subdirectories recursively. Default: `true`. */
|
|
34
|
+
recursive?: boolean;
|
|
35
|
+
}
|
|
36
|
+
interface HotLoaderEvents {
|
|
37
|
+
/** Fires whenever a watched file is modified (before debounce). */
|
|
38
|
+
change: [filePath: string];
|
|
39
|
+
/** Fires after the debounce window with the last changed file path. */
|
|
40
|
+
reload: [filePath: string];
|
|
41
|
+
/** Fires when an error occurs in the watcher. */
|
|
42
|
+
error: [err: Error];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Watches a directory for source file changes and emits typed events. The
|
|
46
|
+
* `restart` helper runs a callback after every debounced `reload`.
|
|
47
|
+
*/
|
|
48
|
+
declare class HotLoader extends EventEmitter {
|
|
49
|
+
private readonly watchPath;
|
|
50
|
+
private readonly debounceMs;
|
|
51
|
+
private readonly extensions;
|
|
52
|
+
private readonly recursive;
|
|
53
|
+
private watcher;
|
|
54
|
+
private debounceTimer;
|
|
55
|
+
private lastChanged;
|
|
56
|
+
private restartFn;
|
|
57
|
+
private restarting;
|
|
58
|
+
constructor(watchPath: string, options?: HotLoaderOptions);
|
|
59
|
+
/**
|
|
60
|
+
* Start watching for file changes.
|
|
61
|
+
*
|
|
62
|
+
* Calling `start()` again after `stop()` is safe — it creates a new watcher.
|
|
63
|
+
*/
|
|
64
|
+
start(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Stop watching. Safe to call even if not started.
|
|
67
|
+
*/
|
|
68
|
+
stop(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Register a callback that runs after every debounced `reload` event.
|
|
71
|
+
*
|
|
72
|
+
* If the callback is already running when another reload fires it will be
|
|
73
|
+
* queued once and run again after the current run finishes.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* loader.restart(async () => {
|
|
78
|
+
* await client.disconnect()
|
|
79
|
+
* await build()
|
|
80
|
+
* await client.connect()
|
|
81
|
+
* })
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
restart(fn: () => void | Promise<void>): void;
|
|
85
|
+
private triggerRestart;
|
|
86
|
+
on<K extends keyof HotLoaderEvents>(event: K, listener: (...args: HotLoaderEvents[K]) => void): this;
|
|
87
|
+
once<K extends keyof HotLoaderEvents>(event: K, listener: (...args: HotLoaderEvents[K]) => void): this;
|
|
88
|
+
off<K extends keyof HotLoaderEvents>(event: K, listener: (...args: HotLoaderEvents[K]) => void): this;
|
|
89
|
+
emit<K extends keyof HotLoaderEvents>(event: K, ...args: HotLoaderEvents[K]): boolean;
|
|
90
|
+
/** Whether the loader is currently active. */
|
|
91
|
+
get watching(): boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { HotLoader, type HotLoaderEvents, type HotLoaderOptions };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module devtools/HotLoader
|
|
5
|
+
*
|
|
6
|
+
* File-watcher utility for development mode (`nova dev`).
|
|
7
|
+
*
|
|
8
|
+
* Uses Node's built-in `fs.watch` — **no external dependencies**.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { HotLoader } from 'novaapp-sdk/devtools'
|
|
13
|
+
*
|
|
14
|
+
* const loader = new HotLoader('./src', { debounce: 300 })
|
|
15
|
+
*
|
|
16
|
+
* loader.on('reload', path => console.log(`Reloading because ${path} changed`))
|
|
17
|
+
* loader.start()
|
|
18
|
+
*
|
|
19
|
+
* // When a module changes, re-run your setup:
|
|
20
|
+
* loader.restart(async () => {
|
|
21
|
+
* await client.disconnect()
|
|
22
|
+
* // ...rebuild / re-require...
|
|
23
|
+
* await client.connect()
|
|
24
|
+
* })
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
interface HotLoaderOptions {
|
|
29
|
+
/** Debounce window in milliseconds before a `reload` event fires. Default: 250ms. */
|
|
30
|
+
debounce?: number;
|
|
31
|
+
/** Extensions to watch. Default: `['.ts', '.js', '.mjs', '.cjs', '.json']`. */
|
|
32
|
+
extensions?: string[];
|
|
33
|
+
/** Whether to watch subdirectories recursively. Default: `true`. */
|
|
34
|
+
recursive?: boolean;
|
|
35
|
+
}
|
|
36
|
+
interface HotLoaderEvents {
|
|
37
|
+
/** Fires whenever a watched file is modified (before debounce). */
|
|
38
|
+
change: [filePath: string];
|
|
39
|
+
/** Fires after the debounce window with the last changed file path. */
|
|
40
|
+
reload: [filePath: string];
|
|
41
|
+
/** Fires when an error occurs in the watcher. */
|
|
42
|
+
error: [err: Error];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Watches a directory for source file changes and emits typed events. The
|
|
46
|
+
* `restart` helper runs a callback after every debounced `reload`.
|
|
47
|
+
*/
|
|
48
|
+
declare class HotLoader extends EventEmitter {
|
|
49
|
+
private readonly watchPath;
|
|
50
|
+
private readonly debounceMs;
|
|
51
|
+
private readonly extensions;
|
|
52
|
+
private readonly recursive;
|
|
53
|
+
private watcher;
|
|
54
|
+
private debounceTimer;
|
|
55
|
+
private lastChanged;
|
|
56
|
+
private restartFn;
|
|
57
|
+
private restarting;
|
|
58
|
+
constructor(watchPath: string, options?: HotLoaderOptions);
|
|
59
|
+
/**
|
|
60
|
+
* Start watching for file changes.
|
|
61
|
+
*
|
|
62
|
+
* Calling `start()` again after `stop()` is safe — it creates a new watcher.
|
|
63
|
+
*/
|
|
64
|
+
start(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Stop watching. Safe to call even if not started.
|
|
67
|
+
*/
|
|
68
|
+
stop(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Register a callback that runs after every debounced `reload` event.
|
|
71
|
+
*
|
|
72
|
+
* If the callback is already running when another reload fires it will be
|
|
73
|
+
* queued once and run again after the current run finishes.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* loader.restart(async () => {
|
|
78
|
+
* await client.disconnect()
|
|
79
|
+
* await build()
|
|
80
|
+
* await client.connect()
|
|
81
|
+
* })
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
restart(fn: () => void | Promise<void>): void;
|
|
85
|
+
private triggerRestart;
|
|
86
|
+
on<K extends keyof HotLoaderEvents>(event: K, listener: (...args: HotLoaderEvents[K]) => void): this;
|
|
87
|
+
once<K extends keyof HotLoaderEvents>(event: K, listener: (...args: HotLoaderEvents[K]) => void): this;
|
|
88
|
+
off<K extends keyof HotLoaderEvents>(event: K, listener: (...args: HotLoaderEvents[K]) => void): this;
|
|
89
|
+
emit<K extends keyof HotLoaderEvents>(event: K, ...args: HotLoaderEvents[K]): boolean;
|
|
90
|
+
/** Whether the loader is currently active. */
|
|
91
|
+
get watching(): boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { HotLoader, type HotLoaderEvents, type HotLoaderOptions };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/devtools/index.ts
|
|
31
|
+
var devtools_exports = {};
|
|
32
|
+
__export(devtools_exports, {
|
|
33
|
+
HotLoader: () => HotLoader
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(devtools_exports);
|
|
36
|
+
|
|
37
|
+
// src/devtools/HotLoader.ts
|
|
38
|
+
var import_node_events = require("events");
|
|
39
|
+
var fs = __toESM(require("fs"));
|
|
40
|
+
var path = __toESM(require("path"));
|
|
41
|
+
var HotLoader = class extends import_node_events.EventEmitter {
|
|
42
|
+
constructor(watchPath, options = {}) {
|
|
43
|
+
super();
|
|
44
|
+
this.watcher = null;
|
|
45
|
+
this.debounceTimer = null;
|
|
46
|
+
this.lastChanged = null;
|
|
47
|
+
this.restartFn = null;
|
|
48
|
+
this.restarting = false;
|
|
49
|
+
this.watchPath = path.resolve(watchPath);
|
|
50
|
+
this.debounceMs = options.debounce ?? 250;
|
|
51
|
+
this.recursive = options.recursive ?? true;
|
|
52
|
+
this.extensions = new Set(
|
|
53
|
+
options.extensions ?? [".ts", ".js", ".mjs", ".cjs", ".json"]
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Start watching for file changes.
|
|
59
|
+
*
|
|
60
|
+
* Calling `start()` again after `stop()` is safe — it creates a new watcher.
|
|
61
|
+
*/
|
|
62
|
+
start() {
|
|
63
|
+
if (this.watcher) return;
|
|
64
|
+
this.watcher = fs.watch(
|
|
65
|
+
this.watchPath,
|
|
66
|
+
{ recursive: this.recursive, encoding: "utf8" },
|
|
67
|
+
(event, filename) => {
|
|
68
|
+
if (!filename) return;
|
|
69
|
+
const ext = path.extname(filename);
|
|
70
|
+
if (!this.extensions.has(ext)) return;
|
|
71
|
+
const full = path.join(this.watchPath, filename);
|
|
72
|
+
this.emit("change", full);
|
|
73
|
+
this.lastChanged = full;
|
|
74
|
+
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
75
|
+
this.debounceTimer = setTimeout(() => {
|
|
76
|
+
this.debounceTimer = null;
|
|
77
|
+
if (this.lastChanged) {
|
|
78
|
+
const f = this.lastChanged;
|
|
79
|
+
this.lastChanged = null;
|
|
80
|
+
this.emit("reload", f);
|
|
81
|
+
this.triggerRestart();
|
|
82
|
+
}
|
|
83
|
+
}, this.debounceMs);
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
this.watcher.on("error", (err) => {
|
|
87
|
+
this.emit("error", err);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Stop watching. Safe to call even if not started.
|
|
92
|
+
*/
|
|
93
|
+
stop() {
|
|
94
|
+
if (this.debounceTimer) {
|
|
95
|
+
clearTimeout(this.debounceTimer);
|
|
96
|
+
this.debounceTimer = null;
|
|
97
|
+
}
|
|
98
|
+
if (this.watcher) {
|
|
99
|
+
this.watcher.close();
|
|
100
|
+
this.watcher = null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ── Restart helper ─────────────────────────────────────────────────────────
|
|
104
|
+
/**
|
|
105
|
+
* Register a callback that runs after every debounced `reload` event.
|
|
106
|
+
*
|
|
107
|
+
* If the callback is already running when another reload fires it will be
|
|
108
|
+
* queued once and run again after the current run finishes.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* loader.restart(async () => {
|
|
113
|
+
* await client.disconnect()
|
|
114
|
+
* await build()
|
|
115
|
+
* await client.connect()
|
|
116
|
+
* })
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
restart(fn) {
|
|
120
|
+
this.restartFn = fn;
|
|
121
|
+
}
|
|
122
|
+
triggerRestart() {
|
|
123
|
+
if (!this.restartFn || this.restarting) return;
|
|
124
|
+
const fn = this.restartFn;
|
|
125
|
+
this.restarting = true;
|
|
126
|
+
const result = fn();
|
|
127
|
+
const finish = () => {
|
|
128
|
+
this.restarting = false;
|
|
129
|
+
};
|
|
130
|
+
if (result instanceof Promise) {
|
|
131
|
+
result.then(finish, (err) => {
|
|
132
|
+
finish();
|
|
133
|
+
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
134
|
+
});
|
|
135
|
+
} else {
|
|
136
|
+
finish();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// ── Typed event overloads ──────────────────────────────────────────────────
|
|
140
|
+
on(event, listener) {
|
|
141
|
+
return super.on(event, listener);
|
|
142
|
+
}
|
|
143
|
+
once(event, listener) {
|
|
144
|
+
return super.once(event, listener);
|
|
145
|
+
}
|
|
146
|
+
off(event, listener) {
|
|
147
|
+
return super.off(event, listener);
|
|
148
|
+
}
|
|
149
|
+
emit(event, ...args) {
|
|
150
|
+
return super.emit(event, ...args);
|
|
151
|
+
}
|
|
152
|
+
/** Whether the loader is currently active. */
|
|
153
|
+
get watching() {
|
|
154
|
+
return this.watcher !== null;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
158
|
+
0 && (module.exports = {
|
|
159
|
+
HotLoader
|
|
160
|
+
});
|