@moostjs/vite 0.5.29 → 0.5.30

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/index.cjs CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  //#region rolldown:runtime
3
2
  var __create = Object.create;
4
3
  var __defProp = Object.defineProperty;
@@ -22,21 +21,56 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
21
  }) : target, mod));
23
22
 
24
23
  //#endregion
25
- const moost = __toESM(require("moost"));
24
+ const magic_string = __toESM(require("magic-string"));
26
25
  const node_fs = __toESM(require("node:fs"));
27
26
  const node_module = __toESM(require("node:module"));
27
+ const moost = __toESM(require("moost"));
28
+
29
+ //#region packages/vite/src/utils.ts
30
+ const PLUGIN_NAME = "moost-vite";
31
+ /**
32
+ * Recursively gathers all importer modules upstream from a given module.
33
+ *
34
+ * @param {EnvironmentModuleNode | undefined} moduleNode - The starting module node.
35
+ * @param {Set<EnvironmentModuleNode>} [visited] - A set of visited modules to avoid duplicates.
36
+ * @returns {Set<EnvironmentModuleNode>} A set containing all discovered importer modules (including the start node).
37
+ */ function gatherAllImporters(moduleNode, visited = /* @__PURE__ */ new Set()) {
38
+ if (!moduleNode) return visited;
39
+ if (visited.has(moduleNode)) return visited;
40
+ visited.add(moduleNode);
41
+ if (moduleNode.importers) for (const importer of moduleNode.importers) gatherAllImporters(importer, visited);
42
+ return visited;
43
+ }
44
+ const logger = new moost.EventLogger("", { level: 99 }).createTopic("\x1B[2m\x1B[36m" + PLUGIN_NAME);
45
+ function getLogger() {
46
+ return logger;
47
+ }
48
+ function getExternals({ node, workspace }) {
49
+ const pkg = JSON.parse((0, node_fs.readFileSync)("package.json", "utf8").toString());
50
+ const externals = workspace ? Object.keys(pkg.dependencies || {}) : Object.entries(pkg.dependencies || {}).filter(([key, ver]) => !ver.startsWith("workspace:")).map((i) => i[0]);
51
+ if (node) externals.push(...node_module.builtinModules, ...node_module.builtinModules.map((m) => `node:${m}`));
52
+ return externals;
53
+ }
28
54
 
55
+ //#endregion
29
56
  //#region packages/vite/src/adapter-detector.ts
30
- function createAdapterDetector(adapter, onInit) {
57
+ /**
58
+ * Creates an adapter detector for a specific adapter type.
59
+ * @param adapter
60
+ * @param onInit
61
+ * @returns
62
+ */ function createAdapterDetector(adapter, onInit) {
31
63
  return {
32
64
  detected: false,
33
- regex: new RegExp(`from\\s+["'](@moostjs\\/event-${adapter})["']`),
65
+ regex: /* @__PURE__ */ new RegExp(`from\\s+["'](@moostjs\\/event-${adapter})["']`),
34
66
  constructor: null,
35
67
  async init() {
36
68
  this.detected = true;
37
69
  const module$1 = await import(`@moostjs/event-${adapter}`);
38
- this.constructor = module$1[`Moost${adapter.charAt(0).toUpperCase() + adapter.slice(1)}`];
39
- if (onInit) onInit(this.constructor);
70
+ const constructorName$1 = `Moost${adapter.charAt(0).toUpperCase() + adapter.slice(1)}`;
71
+ getLogger().log(`🔍 Extracting Adapter "${constructorName$1}"`);
72
+ this.constructor = module$1[constructorName$1];
73
+ if (onInit && this.constructor) onInit(this.constructor);
40
74
  },
41
75
  compare(c) {
42
76
  if (this.detected && this.constructor) return this.constructor === c || c instanceof this.constructor || c.prototype instanceof this.constructor;
@@ -99,7 +133,7 @@ function _define_property(obj, key, value) {
99
133
  * @param {(item: TItem) => void} logRemovedItem - A callback that logs
100
134
  * removed items (presumably by striking them out).
101
135
  */ endRecording(logRemovedItem) {
102
- const newMap = new Map();
136
+ const newMap = /* @__PURE__ */ new Map();
103
137
  for (const item of this.newItems) {
104
138
  const flat = flattenItem(item);
105
139
  newMap.set(flat, item);
@@ -113,7 +147,7 @@ function _define_property(obj, key, value) {
113
147
  /**
114
148
  * A map of flattenItem() => TItem
115
149
  * representing the previous cycle's known handlers.
116
- */ _define_property(this, "oldMap", new Map());
150
+ */ _define_property(this, "oldMap", /* @__PURE__ */ new Map());
117
151
  /**
118
152
  * The handlers discovered in the current cycle,
119
153
  * awaiting finalization.
@@ -125,7 +159,12 @@ function _define_property(obj, key, value) {
125
159
  * A reference to a shared LogsStorage instance that persists
126
160
  * across init cycles in dev mode.
127
161
  */ let logsStorage;
128
- function patchMoostHandlerLogging() {
162
+ /**
163
+ * Patches Moost’s .init() and .logMappedHandler() methods so that, during dev:
164
+ * - Only newly added handlers are logged normally.
165
+ * - Removed handlers are logged/stroked out to indicate removal.
166
+ * - Prevents repeated logs from flooding the console across multiple hot reloads.
167
+ */ function patchMoostHandlerLogging() {
129
168
  const origInit = moost.Moost.prototype.init;
130
169
  /**
131
170
  * Monkey-patch Moost.init:
@@ -155,30 +194,13 @@ function patchMoostHandlerLogging() {
155
194
  };
156
195
  }
157
196
 
158
- //#endregion
159
- //#region packages/vite/src/utils.ts
160
- const PLUGIN_NAME = "moost-vite";
161
- function gatherAllImporters(moduleNode, visited = new Set()) {
162
- if (!moduleNode) return visited;
163
- if (visited.has(moduleNode)) return visited;
164
- visited.add(moduleNode);
165
- if (moduleNode.importers) for (const importer of moduleNode.importers) gatherAllImporters(importer, visited);
166
- return visited;
167
- }
168
- const logger = new moost.EventLogger("", { level: 99 }).createTopic("\x1B[2m\x1B[36m" + PLUGIN_NAME);
169
- function getLogger() {
170
- return logger;
171
- }
172
- function getExternals({ node, workspace }) {
173
- const pkg = JSON.parse((0, node_fs.readFileSync)("package.json", "utf8").toString());
174
- const externals = workspace ? Object.keys(pkg.dependencies || {}) : Object.entries(pkg.dependencies || {}).filter(([key, ver]) => !ver.startsWith("workspace:")).map((i) => i[0]);
175
- if (node) externals.push(...node_module.builtinModules, ...node_module.builtinModules.map((m) => `node:${m}`));
176
- return externals;
177
- }
178
-
179
197
  //#endregion
180
198
  //#region packages/vite/src/restart-cleanup.ts
181
- function moostRestartCleanup(adapters, onEject, cleanupInstances) {
199
+ /**
200
+ * Clean up Moost’s global containers and optionally remove specific instances from the registry.
201
+ *
202
+ * @param {Set<string>} [cleanupInstances] A set of module IDs to remove from the registry.
203
+ */ function moostRestartCleanup(adapters, onEject, cleanupInstances) {
182
204
  const logger$1 = getLogger();
183
205
  const infact = (0, moost.getMoostInfact)();
184
206
  const { registry, scopes } = infact;
@@ -220,7 +242,7 @@ function moostRestartCleanup(adapters, onEject, cleanupInstances) {
220
242
  }
221
243
  function clearDependantRegistry(registry, onEject) {
222
244
  const logger$1 = getLogger();
223
- const objSet = new Set();
245
+ const objSet = /* @__PURE__ */ new Set();
224
246
  let somethingIsDeleted = true;
225
247
  while (somethingIsDeleted) {
226
248
  somethingIsDeleted = false;
@@ -245,7 +267,7 @@ function scanParams(instance, cb) {
245
267
  const mate = (0, moost.getMoostMate)();
246
268
  const params = mate.read(instance)?.params;
247
269
  if (params?.length) for (const param of params) {
248
- if (param.type === undefined || [
270
+ if (param.type === void 0 || [
249
271
  Array,
250
272
  String,
251
273
  Number,
@@ -263,13 +285,33 @@ function constructorName(i) {
263
285
  //#region packages/vite/src/moost-vite.ts
264
286
  /** Regex checks */ const REG_HAS_EXPORT_CLASS = /(^\s*@(Injectable|Controller)\()/m;
265
287
  const REG_REPLACE_EXPORT_CLASS = /(^\s*@(Injectable|Controller)\()/gm;
266
- function moostVite(options) {
288
+ /**
289
+ * The main Vite plugin for integrating Moost applications.
290
+ *
291
+ * Features:
292
+ * - **Adapter Detection**: Detects Moost adapter usage (`http`, `cli`, `wf`) and applies relevant configurations.
293
+ * - **Dev Mode Middleware**:
294
+ * - Patches `MoostHttp.prototype.listen` to register a custom middleware for serving the app via Vite's dev server instead of binding to a port.
295
+ * - Handles Moost state cleanup and hot module replacement (HMR) during development.
296
+ * - **Class Tracking**: Injects a `__VITE_ID()` decorator into exported classes to enable tracking and cleanup during hot reloads.
297
+ * - **Externals Support**:
298
+ * - Allows marking Node.js built-in modules and dependencies from `package.json` (optionally excluding workspace dependencies) as external during builds.
299
+ * - Configured via the `externals` option, which helps reduce bundle size and ensures compatibility with runtime environments.
300
+ * - **Build and Test Friendly**:
301
+ * - Avoids interfering with Vitest runs by skipping dev-specific behaviors during tests.
302
+ * - Ensures proper SSR entry setup and Rollup configurations for production builds.
303
+ *
304
+ * @param {TMoostViteDevOptions} options - Configuration options for the Moost Vite plugin.
305
+ * @returns {PluginOption} The configured Vite plugin.
306
+ */ function moostVite(options) {
267
307
  const isTest = process.env.NODE_ENV === "test";
268
308
  const isProd = process.env.NODE_ENV === "production";
309
+ const externals = options.externals ?? true;
269
310
  let moostMiddleware = null;
270
311
  const adapters = isTest ? [] : [
271
312
  createAdapterDetector("http", (MoostHttp) => {
272
313
  MoostHttp.prototype.listen = function(...args) {
314
+ logger$1.log("🔌 \x1B[2mOvertaking HTTP.listen");
273
315
  moostMiddleware = this.getServerCb();
274
316
  setTimeout(() => {
275
317
  args.filter((a) => typeof a === "function").forEach((a) => a());
@@ -288,14 +330,14 @@ function moostVite(options) {
288
330
  enforce: "pre",
289
331
  config(cfg) {
290
332
  const entry = cfg.build?.rollupOptions?.input || options.entry;
291
- const outfile = typeof entry === "string" ? entry.split("/").pop().replace(/\.ts$/, ".js") : undefined;
333
+ const outfile = typeof entry === "string" ? entry.split("/").pop().replace(/\.ts$/, ".js") : void 0;
292
334
  return {
293
335
  server: {
294
336
  port: cfg.server?.port || options.port || 3e3,
295
337
  host: cfg.server?.host || options.host
296
338
  },
297
339
  optimizeDeps: {
298
- noDiscovery: cfg.optimizeDeps?.noDiscovery === undefined ? true : cfg.optimizeDeps.noDiscovery,
340
+ noDiscovery: cfg.optimizeDeps?.noDiscovery === void 0 ? true : cfg.optimizeDeps.noDiscovery,
299
341
  exclude: cfg.optimizeDeps?.exclude || ["@swc/core"]
300
342
  },
301
343
  build: {
@@ -303,15 +345,15 @@ function moostVite(options) {
303
345
  outDir: cfg.build?.outDir || options.outDir || "dist",
304
346
  ssr: cfg.build?.ssr ?? true,
305
347
  minify: cfg.build?.minify || false,
348
+ sourcemap: !!(options.sourcemap ?? true),
306
349
  rollupOptions: {
307
- external: isTest ? cfg.build?.rollupOptions?.external : cfg.build?.rollupOptions?.external || (options.externals === false ? [] : getExternals({
308
- node: Boolean(options.externals === true || options.externals?.node),
309
- workspace: Boolean(options.externals === true || options.externals?.workspace)
350
+ external: isTest ? cfg.build?.rollupOptions?.external : cfg.build?.rollupOptions?.external || (externals === false ? [] : getExternals({
351
+ node: Boolean(externals === true || externals?.node),
352
+ workspace: Boolean(externals === true || externals?.workspace)
310
353
  })),
311
354
  input: entry,
312
355
  output: {
313
356
  format: options.format,
314
- sourcemap: !!(options.sourcemap ?? true),
315
357
  entryFileNames: outfile,
316
358
  ...cfg.build?.rollupOptions?.output
317
359
  }
@@ -320,25 +362,33 @@ function moostVite(options) {
320
362
  };
321
363
  },
322
364
  async transform(code, id) {
323
- if (!id.endsWith(".ts")) return code;
365
+ if (!id.endsWith(".ts")) return null;
324
366
  for (const adapter of adapters) if (!adapter.detected && adapter.regex.test(code)) await adapter.init();
325
367
  if (REG_HAS_EXPORT_CLASS.test(code)) {
326
- code = code.replace(REG_REPLACE_EXPORT_CLASS, "\n@__VITE_ID(import.meta.filename)\n$1");
327
- code = `import { __VITE_ID } from 'virtual:vite-id'\n\n${code}`;
368
+ const s = new magic_string.default(code);
369
+ s.replace(REG_REPLACE_EXPORT_CLASS, "\n@__VITE_ID(import.meta.filename)\n$1");
370
+ s.prepend(`import { __VITE_ID } from 'virtual:vite-id'\n\n`);
371
+ return {
372
+ code: s.toString(),
373
+ map: s.generateMap({ hires: true })
374
+ };
328
375
  }
329
- return code;
376
+ return null;
330
377
  },
331
378
  resolveId(id) {
332
379
  if (id === "virtual:vite-id") return "\0virtual:vite-id";
333
380
  },
334
381
  load(id) {
335
- if (id === "\0virtual:vite-id") return `
382
+ if (id === "\0virtual:vite-id") return {
383
+ code: `
336
384
  import { getMoostMate } from "moost";
337
385
  const mate = getMoostMate();
338
386
  export function __VITE_ID(id) {
339
387
  return mate.decorate("__vite_id", id)
340
388
  }
341
- `;
389
+ `,
390
+ map: null
391
+ };
342
392
  },
343
393
  async configureServer(server) {
344
394
  moostRestartCleanup(adapters, options.onEject);
@@ -361,7 +411,7 @@ function moostVite(options) {
361
411
  const modules = this.environment.moduleGraph.getModulesByFile(file);
362
412
  if (modules) {
363
413
  logger$1.debug(`🔃 Hot update: ${file}`);
364
- const cleanupInstances = new Set();
414
+ const cleanupInstances = /* @__PURE__ */ new Set();
365
415
  for (const mod of modules) {
366
416
  const allImporters = gatherAllImporters(mod);
367
417
  for (const impModule of allImporters) if (impModule.id) cleanupInstances.add(impModule.id);
@@ -386,4 +436,4 @@ function moostVite(options) {
386
436
  }
387
437
 
388
438
  //#endregion
389
- exports.moostVite = moostVite
439
+ exports.moostVite = moostVite;
package/dist/index.d.ts CHANGED
@@ -1,18 +1,90 @@
1
- import { Plugin } from 'vite';
1
+ import { PluginOption } from 'vite';
2
2
 
3
3
  interface TMoostViteDevOptions {
4
+ /**
5
+ * The entry file for the application.
6
+ * This file serves as the main entry point for the build process and SSR server.
7
+ *
8
+ * Example: './src/main.ts'
9
+ */
4
10
  entry: string;
11
+ /**
12
+ * The port number for the Vite dev server.
13
+ *
14
+ * Default: `3000`.
15
+ */
5
16
  port?: number;
17
+ /**
18
+ * The hostname or IP address for the Vite dev server.
19
+ * If not specified, defaults to `'localhost'`.
20
+ *
21
+ * Example: '0.0.0.0'
22
+ */
6
23
  host?: string;
24
+ /**
25
+ * The output directory for the build artifacts.
26
+ *
27
+ * Default to: `'dist'`.
28
+ */
7
29
  outDir?: string;
30
+ /**
31
+ * The output format for the build artifacts.
32
+ * - `'cjs'`: CommonJS, suitable for Node.js environments.
33
+ * - `'esm'`: ES Module, suitable for modern environments.
34
+ *
35
+ * Default: `'esm'`.
36
+ */
8
37
  format?: 'cjs' | 'esm';
38
+ /**
39
+ * Whether to generate source maps for the build output.
40
+ * Source maps are useful for debugging purposes by mapping minified code back to the original source.
41
+ *
42
+ * Default: `true`.
43
+ */
9
44
  sourcemap?: boolean;
45
+ /**
46
+ * Configuration for defining external dependencies during the build process.
47
+ *
48
+ * This helps in excluding certain modules from the bundled output, reducing the bundle size and
49
+ * allowing them to be resolved at runtime instead.
50
+ *
51
+ * Default: `true`.
52
+ */
10
53
  externals?: {
54
+ /**
55
+ * Whether to exclude Node.js built-in modules (e.g., `fs`, `path`, `node:fs`) from the build output.
56
+ * If `true`, all Node.js built-ins will be marked as external.
57
+ * Default: `false`.
58
+ */
11
59
  node?: boolean;
60
+ /**
61
+ * Whether to exclude workspace dependencies (e.g., packages marked with `workspace:*` in `package.json`) from the build output.
62
+ * If `true`, all workspace dependencies will be marked as external.
63
+ * Default: `false`.
64
+ */
12
65
  workspace?: boolean;
13
66
  } | boolean;
14
67
  onEject?: (instance: object, dependency: Function) => boolean;
15
68
  }
16
- declare function moostVite(options: TMoostViteDevOptions): Plugin;
69
+ /**
70
+ * The main Vite plugin for integrating Moost applications.
71
+ *
72
+ * Features:
73
+ * - **Adapter Detection**: Detects Moost adapter usage (`http`, `cli`, `wf`) and applies relevant configurations.
74
+ * - **Dev Mode Middleware**:
75
+ * - Patches `MoostHttp.prototype.listen` to register a custom middleware for serving the app via Vite's dev server instead of binding to a port.
76
+ * - Handles Moost state cleanup and hot module replacement (HMR) during development.
77
+ * - **Class Tracking**: Injects a `__VITE_ID()` decorator into exported classes to enable tracking and cleanup during hot reloads.
78
+ * - **Externals Support**:
79
+ * - Allows marking Node.js built-in modules and dependencies from `package.json` (optionally excluding workspace dependencies) as external during builds.
80
+ * - Configured via the `externals` option, which helps reduce bundle size and ensures compatibility with runtime environments.
81
+ * - **Build and Test Friendly**:
82
+ * - Avoids interfering with Vitest runs by skipping dev-specific behaviors during tests.
83
+ * - Ensures proper SSR entry setup and Rollup configurations for production builds.
84
+ *
85
+ * @param {TMoostViteDevOptions} options - Configuration options for the Moost Vite plugin.
86
+ * @returns {PluginOption} The configured Vite plugin.
87
+ */
88
+ declare function moostVite(options: TMoostViteDevOptions): PluginOption;
17
89
 
18
90
  export { moostVite };
package/dist/index.mjs CHANGED
@@ -1,18 +1,53 @@
1
- import { EventLogger, Moost, clearGlobalWooks, getMoostInfact, getMoostMate } from "moost";
1
+ import MagicString from "magic-string";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { builtinModules } from "node:module";
4
+ import { EventLogger, Moost, clearGlobalWooks, getMoostInfact, getMoostMate } from "moost";
5
+
6
+ //#region packages/vite/src/utils.ts
7
+ const PLUGIN_NAME = "moost-vite";
8
+ /**
9
+ * Recursively gathers all importer modules upstream from a given module.
10
+ *
11
+ * @param {EnvironmentModuleNode | undefined} moduleNode - The starting module node.
12
+ * @param {Set<EnvironmentModuleNode>} [visited] - A set of visited modules to avoid duplicates.
13
+ * @returns {Set<EnvironmentModuleNode>} A set containing all discovered importer modules (including the start node).
14
+ */ function gatherAllImporters(moduleNode, visited = /* @__PURE__ */ new Set()) {
15
+ if (!moduleNode) return visited;
16
+ if (visited.has(moduleNode)) return visited;
17
+ visited.add(moduleNode);
18
+ if (moduleNode.importers) for (const importer of moduleNode.importers) gatherAllImporters(importer, visited);
19
+ return visited;
20
+ }
21
+ const logger = new EventLogger("", { level: 99 }).createTopic("\x1B[2m\x1B[36m" + PLUGIN_NAME);
22
+ function getLogger() {
23
+ return logger;
24
+ }
25
+ function getExternals({ node, workspace }) {
26
+ const pkg = JSON.parse(readFileSync("package.json", "utf8").toString());
27
+ const externals = workspace ? Object.keys(pkg.dependencies || {}) : Object.entries(pkg.dependencies || {}).filter(([key, ver]) => !ver.startsWith("workspace:")).map((i) => i[0]);
28
+ if (node) externals.push(...builtinModules, ...builtinModules.map((m) => `node:${m}`));
29
+ return externals;
30
+ }
4
31
 
32
+ //#endregion
5
33
  //#region packages/vite/src/adapter-detector.ts
6
- function createAdapterDetector(adapter, onInit) {
34
+ /**
35
+ * Creates an adapter detector for a specific adapter type.
36
+ * @param adapter
37
+ * @param onInit
38
+ * @returns
39
+ */ function createAdapterDetector(adapter, onInit) {
7
40
  return {
8
41
  detected: false,
9
- regex: new RegExp(`from\\s+["'](@moostjs\\/event-${adapter})["']`),
42
+ regex: /* @__PURE__ */ new RegExp(`from\\s+["'](@moostjs\\/event-${adapter})["']`),
10
43
  constructor: null,
11
44
  async init() {
12
45
  this.detected = true;
13
46
  const module = await import(`@moostjs/event-${adapter}`);
14
- this.constructor = module[`Moost${adapter.charAt(0).toUpperCase() + adapter.slice(1)}`];
15
- if (onInit) onInit(this.constructor);
47
+ const constructorName$1 = `Moost${adapter.charAt(0).toUpperCase() + adapter.slice(1)}`;
48
+ getLogger().log(`🔍 Extracting Adapter "${constructorName$1}"`);
49
+ this.constructor = module[constructorName$1];
50
+ if (onInit && this.constructor) onInit(this.constructor);
16
51
  },
17
52
  compare(c) {
18
53
  if (this.detected && this.constructor) return this.constructor === c || c instanceof this.constructor || c.prototype instanceof this.constructor;
@@ -75,7 +110,7 @@ function _define_property(obj, key, value) {
75
110
  * @param {(item: TItem) => void} logRemovedItem - A callback that logs
76
111
  * removed items (presumably by striking them out).
77
112
  */ endRecording(logRemovedItem) {
78
- const newMap = new Map();
113
+ const newMap = /* @__PURE__ */ new Map();
79
114
  for (const item of this.newItems) {
80
115
  const flat = flattenItem(item);
81
116
  newMap.set(flat, item);
@@ -89,7 +124,7 @@ function _define_property(obj, key, value) {
89
124
  /**
90
125
  * A map of flattenItem() => TItem
91
126
  * representing the previous cycle's known handlers.
92
- */ _define_property(this, "oldMap", new Map());
127
+ */ _define_property(this, "oldMap", /* @__PURE__ */ new Map());
93
128
  /**
94
129
  * The handlers discovered in the current cycle,
95
130
  * awaiting finalization.
@@ -101,7 +136,12 @@ function _define_property(obj, key, value) {
101
136
  * A reference to a shared LogsStorage instance that persists
102
137
  * across init cycles in dev mode.
103
138
  */ let logsStorage;
104
- function patchMoostHandlerLogging() {
139
+ /**
140
+ * Patches Moost’s .init() and .logMappedHandler() methods so that, during dev:
141
+ * - Only newly added handlers are logged normally.
142
+ * - Removed handlers are logged/stroked out to indicate removal.
143
+ * - Prevents repeated logs from flooding the console across multiple hot reloads.
144
+ */ function patchMoostHandlerLogging() {
105
145
  const origInit = Moost.prototype.init;
106
146
  /**
107
147
  * Monkey-patch Moost.init:
@@ -131,30 +171,13 @@ function patchMoostHandlerLogging() {
131
171
  };
132
172
  }
133
173
 
134
- //#endregion
135
- //#region packages/vite/src/utils.ts
136
- const PLUGIN_NAME = "moost-vite";
137
- function gatherAllImporters(moduleNode, visited = new Set()) {
138
- if (!moduleNode) return visited;
139
- if (visited.has(moduleNode)) return visited;
140
- visited.add(moduleNode);
141
- if (moduleNode.importers) for (const importer of moduleNode.importers) gatherAllImporters(importer, visited);
142
- return visited;
143
- }
144
- const logger = new EventLogger("", { level: 99 }).createTopic("\x1B[2m\x1B[36m" + PLUGIN_NAME);
145
- function getLogger() {
146
- return logger;
147
- }
148
- function getExternals({ node, workspace }) {
149
- const pkg = JSON.parse(readFileSync("package.json", "utf8").toString());
150
- const externals = workspace ? Object.keys(pkg.dependencies || {}) : Object.entries(pkg.dependencies || {}).filter(([key, ver]) => !ver.startsWith("workspace:")).map((i) => i[0]);
151
- if (node) externals.push(...builtinModules, ...builtinModules.map((m) => `node:${m}`));
152
- return externals;
153
- }
154
-
155
174
  //#endregion
156
175
  //#region packages/vite/src/restart-cleanup.ts
157
- function moostRestartCleanup(adapters, onEject, cleanupInstances) {
176
+ /**
177
+ * Clean up Moost’s global containers and optionally remove specific instances from the registry.
178
+ *
179
+ * @param {Set<string>} [cleanupInstances] A set of module IDs to remove from the registry.
180
+ */ function moostRestartCleanup(adapters, onEject, cleanupInstances) {
158
181
  const logger$1 = getLogger();
159
182
  const infact = getMoostInfact();
160
183
  const { registry, scopes } = infact;
@@ -196,7 +219,7 @@ function moostRestartCleanup(adapters, onEject, cleanupInstances) {
196
219
  }
197
220
  function clearDependantRegistry(registry, onEject) {
198
221
  const logger$1 = getLogger();
199
- const objSet = new Set();
222
+ const objSet = /* @__PURE__ */ new Set();
200
223
  let somethingIsDeleted = true;
201
224
  while (somethingIsDeleted) {
202
225
  somethingIsDeleted = false;
@@ -221,7 +244,7 @@ function scanParams(instance, cb) {
221
244
  const mate = getMoostMate();
222
245
  const params = mate.read(instance)?.params;
223
246
  if (params?.length) for (const param of params) {
224
- if (param.type === undefined || [
247
+ if (param.type === void 0 || [
225
248
  Array,
226
249
  String,
227
250
  Number,
@@ -239,13 +262,33 @@ function constructorName(i) {
239
262
  //#region packages/vite/src/moost-vite.ts
240
263
  /** Regex checks */ const REG_HAS_EXPORT_CLASS = /(^\s*@(Injectable|Controller)\()/m;
241
264
  const REG_REPLACE_EXPORT_CLASS = /(^\s*@(Injectable|Controller)\()/gm;
242
- function moostVite(options) {
265
+ /**
266
+ * The main Vite plugin for integrating Moost applications.
267
+ *
268
+ * Features:
269
+ * - **Adapter Detection**: Detects Moost adapter usage (`http`, `cli`, `wf`) and applies relevant configurations.
270
+ * - **Dev Mode Middleware**:
271
+ * - Patches `MoostHttp.prototype.listen` to register a custom middleware for serving the app via Vite's dev server instead of binding to a port.
272
+ * - Handles Moost state cleanup and hot module replacement (HMR) during development.
273
+ * - **Class Tracking**: Injects a `__VITE_ID()` decorator into exported classes to enable tracking and cleanup during hot reloads.
274
+ * - **Externals Support**:
275
+ * - Allows marking Node.js built-in modules and dependencies from `package.json` (optionally excluding workspace dependencies) as external during builds.
276
+ * - Configured via the `externals` option, which helps reduce bundle size and ensures compatibility with runtime environments.
277
+ * - **Build and Test Friendly**:
278
+ * - Avoids interfering with Vitest runs by skipping dev-specific behaviors during tests.
279
+ * - Ensures proper SSR entry setup and Rollup configurations for production builds.
280
+ *
281
+ * @param {TMoostViteDevOptions} options - Configuration options for the Moost Vite plugin.
282
+ * @returns {PluginOption} The configured Vite plugin.
283
+ */ function moostVite(options) {
243
284
  const isTest = false;
244
285
  const isProd = false;
286
+ const externals = options.externals ?? true;
245
287
  let moostMiddleware = null;
246
288
  const adapters = isTest ? [] : [
247
289
  createAdapterDetector("http", (MoostHttp) => {
248
290
  MoostHttp.prototype.listen = function(...args) {
291
+ logger$1.log("🔌 \x1B[2mOvertaking HTTP.listen");
249
292
  moostMiddleware = this.getServerCb();
250
293
  setTimeout(() => {
251
294
  args.filter((a) => typeof a === "function").forEach((a) => a());
@@ -264,14 +307,14 @@ function moostVite(options) {
264
307
  enforce: "pre",
265
308
  config(cfg) {
266
309
  const entry = cfg.build?.rollupOptions?.input || options.entry;
267
- const outfile = typeof entry === "string" ? entry.split("/").pop().replace(/\.ts$/, ".js") : undefined;
310
+ const outfile = typeof entry === "string" ? entry.split("/").pop().replace(/\.ts$/, ".js") : void 0;
268
311
  return {
269
312
  server: {
270
313
  port: cfg.server?.port || options.port || 3e3,
271
314
  host: cfg.server?.host || options.host
272
315
  },
273
316
  optimizeDeps: {
274
- noDiscovery: cfg.optimizeDeps?.noDiscovery === undefined ? true : cfg.optimizeDeps.noDiscovery,
317
+ noDiscovery: cfg.optimizeDeps?.noDiscovery === void 0 ? true : cfg.optimizeDeps.noDiscovery,
275
318
  exclude: cfg.optimizeDeps?.exclude || ["@swc/core"]
276
319
  },
277
320
  build: {
@@ -279,15 +322,15 @@ function moostVite(options) {
279
322
  outDir: cfg.build?.outDir || options.outDir || "dist",
280
323
  ssr: cfg.build?.ssr ?? true,
281
324
  minify: cfg.build?.minify || false,
325
+ sourcemap: !!(options.sourcemap ?? true),
282
326
  rollupOptions: {
283
- external: isTest ? cfg.build?.rollupOptions?.external : cfg.build?.rollupOptions?.external || (options.externals === false ? [] : getExternals({
284
- node: Boolean(options.externals === true || options.externals?.node),
285
- workspace: Boolean(options.externals === true || options.externals?.workspace)
327
+ external: isTest ? cfg.build?.rollupOptions?.external : cfg.build?.rollupOptions?.external || (externals === false ? [] : getExternals({
328
+ node: Boolean(externals === true || externals?.node),
329
+ workspace: Boolean(externals === true || externals?.workspace)
286
330
  })),
287
331
  input: entry,
288
332
  output: {
289
333
  format: options.format,
290
- sourcemap: !!(options.sourcemap ?? true),
291
334
  entryFileNames: outfile,
292
335
  ...cfg.build?.rollupOptions?.output
293
336
  }
@@ -296,25 +339,33 @@ function moostVite(options) {
296
339
  };
297
340
  },
298
341
  async transform(code, id) {
299
- if (!id.endsWith(".ts")) return code;
342
+ if (!id.endsWith(".ts")) return null;
300
343
  for (const adapter of adapters) if (!adapter.detected && adapter.regex.test(code)) await adapter.init();
301
344
  if (REG_HAS_EXPORT_CLASS.test(code)) {
302
- code = code.replace(REG_REPLACE_EXPORT_CLASS, "\n@__VITE_ID(import.meta.filename)\n$1");
303
- code = `import { __VITE_ID } from 'virtual:vite-id'\n\n${code}`;
345
+ const s = new MagicString(code);
346
+ s.replace(REG_REPLACE_EXPORT_CLASS, "\n@__VITE_ID(import.meta.filename)\n$1");
347
+ s.prepend(`import { __VITE_ID } from 'virtual:vite-id'\n\n`);
348
+ return {
349
+ code: s.toString(),
350
+ map: s.generateMap({ hires: true })
351
+ };
304
352
  }
305
- return code;
353
+ return null;
306
354
  },
307
355
  resolveId(id) {
308
356
  if (id === "virtual:vite-id") return "\0virtual:vite-id";
309
357
  },
310
358
  load(id) {
311
- if (id === "\0virtual:vite-id") return `
359
+ if (id === "\0virtual:vite-id") return {
360
+ code: `
312
361
  import { getMoostMate } from "moost";
313
362
  const mate = getMoostMate();
314
363
  export function __VITE_ID(id) {
315
364
  return mate.decorate("__vite_id", id)
316
365
  }
317
- `;
366
+ `,
367
+ map: null
368
+ };
318
369
  },
319
370
  async configureServer(server) {
320
371
  moostRestartCleanup(adapters, options.onEject);
@@ -337,7 +388,7 @@ function moostVite(options) {
337
388
  const modules = this.environment.moduleGraph.getModulesByFile(file);
338
389
  if (modules) {
339
390
  logger$1.debug(`🔃 Hot update: ${file}`);
340
- const cleanupInstances = new Set();
391
+ const cleanupInstances = /* @__PURE__ */ new Set();
341
392
  for (const mod of modules) {
342
393
  const allImporters = gatherAllImporters(mod);
343
394
  for (const impModule of allImporters) if (impModule.id) cleanupInstances.add(impModule.id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moostjs/vite",
3
- "version": "0.5.29",
3
+ "version": "0.5.30",
4
4
  "description": "Vite Dev plugin for moostjs",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -38,12 +38,15 @@
38
38
  },
39
39
  "homepage": "https://github.com/moostjs/moostjs/tree/main/packages/vite#readme",
40
40
  "peerDependencies": {
41
- "vite": "^6.0.5",
42
- "moost": "^0.5.29",
43
- "@moostjs/event-http": "^0.5.29"
41
+ "vite": "^7.0.0",
42
+ "@moostjs/event-http": "^0.5.30",
43
+ "moost": "^0.5.30"
44
44
  },
45
45
  "devDependencies": {
46
- "vitest": "^3.0.5"
46
+ "vitest": "3.2.4"
47
+ },
48
+ "dependencies": {
49
+ "magic-string": "^0.30.17"
47
50
  },
48
51
  "scripts": {
49
52
  "pub": "pnpm publish --access public",