@fluixi/vite-plugin 1.0.0-alpha.82 → 1.0.0-alpha.84

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 +1,213 @@
1
- "use strict";var o=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var f=(i,t)=>{for(var p in t)o(i,p,{get:t[p],enumerable:!0})},s=(i,t,p,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of x(t))!m.call(i,e)&&e!==p&&o(i,e,{get:()=>t[e],enumerable:!(n=u(t,e))||n.enumerable});return i};var O=i=>s(o({},"__esModule",{value:!0}),i);var y={};f(y,{createVitePlugin:()=>r.createVitePlugin,default:()=>g,fluixi:()=>l});module.exports=O(y);var r=require("@fluixi/compiler/integrations");function l(i={}){return(0,r.createVitePlugin)(i)}var g=l;
1
+ /*! @fluixi/vite-plugin v1.0.0-alpha.84 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.ts
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ createVitePlugin: () => import_integrations.createVitePlugin,
35
+ default: () => index_default,
36
+ fluixi: () => fluixi
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+ var import_integrations = require("@fluixi/compiler/integrations");
40
+
41
+ // src/graph-channel.ts
42
+ var import_node_module = require("node:module");
43
+ var import_node_path = require("node:path");
44
+ var import_meta = {};
45
+ var VIRTUAL = "virtual:fluixi/devtools-agent";
46
+ var RESOLVED = `\0${VIRTUAL}`;
47
+ var ENDPOINT = "/__fluixi/graph";
48
+ var EVENT = "fluixi:graph";
49
+ var MISSING = "the plugin could not load @fluixi/devtools from its own dependencies";
50
+ var WAITING = "no page has reported yet — open the application in a browser";
51
+ var INTERVAL = 100;
52
+ var HISTORY = 500;
53
+ var agentSource = (devtools, plugins, signal, reactive) => `
54
+ import { installDevtoolsHook, observeGraph } from ${JSON.stringify(devtools)};
55
+ import ${JSON.stringify(plugins)};
56
+ import { observeReactiveNodes } from ${JSON.stringify(signal)};
57
+ import { VERSION } from ${JSON.stringify(reactive)};
58
+
59
+ // The runtime this module imports is the application's own — same module graph, same nodes.
60
+ // Nothing waits for the runtime to offer itself; that path is for a tool loaded from outside.
61
+ //
62
+ // \`watch\` is this copy of devtools, handed over with the runtime. A browser extension
63
+ // installs a hook at document_start and so owns it; without this the graph would be built
64
+ // by that extension's build rather than the one shipped alongside this application.
65
+ const hook = installDevtoolsHook();
66
+ hook.inject({ observeReactiveNodes, version: VERSION, watch: observeGraph });
67
+
68
+ const send = (kind, snapshot) => import.meta.hot?.send(${JSON.stringify(EVENT)}, { kind, snapshot });
69
+
70
+ const first = hook.snapshot();
71
+ // Kept and handed back, so a browser panel polling the same hook cannot consume what this
72
+ // one has not been told about yet.
73
+ let cursor = first?.cursor;
74
+ send('full', first);
75
+ const timer = setInterval(() => {
76
+ const delta = hook.snapshot({ partial: true, since: cursor });
77
+ if (!delta) return;
78
+ cursor = delta.cursor;
79
+ // Events count on their own: an effect that ran without changing a value moves no node.
80
+ if (delta.nodes.length || delta.removed?.length || delta.events?.length) send('delta', delta);
81
+ }, ${INTERVAL});
82
+
83
+ import.meta.hot?.dispose(() => clearInterval(timer));
84
+ `;
85
+ function ownDevtools() {
86
+ try {
87
+ return (0, import_node_module.createRequire)(import_meta.url).resolve("@fluixi/devtools");
88
+ } catch {
89
+ return null;
90
+ }
91
+ }
92
+ function ownPlugins() {
93
+ try {
94
+ return (0, import_node_module.createRequire)(import_meta.url).resolve("@fluixi/devtools/plugins");
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+ function withGraphChannel(base, enabled, start) {
100
+ let wire = null;
101
+ let available = false;
102
+ let reason = MISSING;
103
+ let root = process.cwd();
104
+ let log;
105
+ let graph = /* @__PURE__ */ new Map();
106
+ let stamp = 0;
107
+ let events = [];
108
+ const baseResolveId = base.resolveId;
109
+ const baseTransformIndexHtml = base.transformIndexHtml;
110
+ return {
111
+ ...base,
112
+ resolveId(id, importer) {
113
+ if (id === VIRTUAL) return RESOLVED;
114
+ return baseResolveId?.call(this, id, importer) ?? null;
115
+ },
116
+ async load(id) {
117
+ if (id !== RESOLVED) return null;
118
+ const from = (0, import_node_path.join)(root, "fluixi-devtools-agent.js");
119
+ const specs = ["@fluixi/reactive/signal", "@fluixi/reactive"];
120
+ const ids = await Promise.all(specs.map((spec) => this.resolve?.(spec, from, { skipSelf: true })));
121
+ const missing = specs.filter((_, i) => !ids[i]?.id);
122
+ const devtools = ownDevtools();
123
+ const plugins = ownPlugins();
124
+ if (missing.length || !devtools || !plugins) {
125
+ reason = missing.length ? `${missing.join(", ")} did not resolve from ${root}` : MISSING;
126
+ log?.(`[fluixi] reactive graph off — ${reason}`);
127
+ return "export {};";
128
+ }
129
+ return agentSource(`/@fs/${devtools}`, `/@fs/${plugins}`, ids[0].id, ids[1].id);
130
+ },
131
+ async configureServer(server) {
132
+ if (!enabled()) return;
133
+ root = server.config?.root ?? root;
134
+ log = server.config?.logger?.info.bind(server.config.logger);
135
+ wire = await import("@fluixi/devtools/wire").catch(() => null);
136
+ available = wire !== null;
137
+ if (wire) start();
138
+ if (wire) reason = WAITING;
139
+ else {
140
+ log?.(`[fluixi] reactive graph off — ${MISSING}`);
141
+ }
142
+ server.middlewares.use(ENDPOINT, (_req, res) => {
143
+ const snapshot = wire ? { ...wire.serializeGraph(graph, stamp || Date.now()), events } : { t: Date.now(), nodes: [] };
144
+ const body = JSON.stringify(reason ? { ...snapshot, reason } : snapshot);
145
+ res.setHeader("Content-Type", "application/json");
146
+ res.setHeader("Access-Control-Allow-Origin", "*");
147
+ res.setHeader("Cache-Control", "no-store");
148
+ res.end(body);
149
+ });
150
+ if (!wire) return;
151
+ server.ws.on(EVENT, (payload) => {
152
+ const message = payload;
153
+ if (!message?.snapshot || !wire) return;
154
+ const full = message.kind === "full";
155
+ graph = wire.applySnapshot(full ? /* @__PURE__ */ new Map() : graph, message.snapshot);
156
+ if (full) events = [];
157
+ const arriving = message.snapshot.events;
158
+ if (arriving?.length) events = [...events, ...arriving].slice(-HISTORY);
159
+ stamp = Date.now();
160
+ reason = null;
161
+ });
162
+ },
163
+ transformIndexHtml: {
164
+ order: "pre",
165
+ handler(html, ctx) {
166
+ const inherited = callInheritedHtml(baseTransformIndexHtml, html, ctx);
167
+ if (!enabled() || !available || !wire) return inherited;
168
+ return {
169
+ html: typeof inherited === "string" ? inherited : html,
170
+ tags: [
171
+ {
172
+ tag: "script",
173
+ // First in the head, so the entry cannot create a node before the agent runs.
174
+ injectTo: "head-prepend",
175
+ attrs: { type: "module", src: `/@id/${VIRTUAL}` }
176
+ }
177
+ ]
178
+ };
179
+ }
180
+ }
181
+ };
182
+ }
183
+ function callInheritedHtml(hook, html, ctx) {
184
+ if (typeof hook === "function") return hook(html, ctx);
185
+ const handler = hook?.handler;
186
+ return handler?.(html, ctx);
187
+ }
188
+
189
+ // src/index.ts
190
+ function fluixi(options = {}) {
191
+ const settings = options;
192
+ let serving = false;
193
+ const enabled = () => serving && settings.devtools !== false;
194
+ const base = (0, import_integrations.createVitePlugin)(settings);
195
+ const inherited = base.configResolved;
196
+ const start = () => {
197
+ settings.sourceLocations = true;
198
+ settings.sourceLocationsExternal = typeof settings.devtools === "object" && settings.devtools.external === true;
199
+ };
200
+ return withGraphChannel(
201
+ {
202
+ ...base,
203
+ configResolved(config) {
204
+ inherited?.(config);
205
+ serving = config?.command === "serve";
206
+ settings.sourceRoot = config.root;
207
+ }
208
+ },
209
+ enabled,
210
+ start
211
+ );
212
+ }
213
+ var index_default = fluixi;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEvF,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAE9D;AAED,eAAe,MAAM,CAAC;AAGtB,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGvF,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAqC9D;AAED,eAAe,MAAM,CAAC;AAGtB,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAC5B,YAAY,EAAE,eAAe,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createVitePlugin } from '@fluixi/compiler/integrations';
2
+ import { withGraphChannel } from './graph-channel.js';
2
3
  /**
3
4
  * Fluixi Vite plugin.
4
5
  *
@@ -13,7 +14,31 @@ import { createVitePlugin } from '@fluixi/compiler/integrations';
13
14
  * ```
14
15
  */
15
16
  export function fluixi(options = {}) {
16
- return createVitePlugin(options);
17
+ // The compiler reads this object per transform, so turning source marks on once the
18
+ // command is known reaches every file — they are worth their size in dev and nothing in a
19
+ // build, which is why the answer waits for configResolved.
20
+ const settings = options;
21
+ let serving = false;
22
+ const enabled = () => serving && settings.devtools !== false;
23
+ const base = createVitePlugin(settings);
24
+ const inherited = base.configResolved;
25
+ const start = () => {
26
+ settings.sourceLocations = true;
27
+ // Marking a dependency is for someone working on the framework, so it is asked for.
28
+ settings.sourceLocationsExternal =
29
+ typeof settings.devtools === 'object' && settings.devtools.external === true;
30
+ };
31
+ return withGraphChannel({
32
+ ...base,
33
+ configResolved(config) {
34
+ inherited?.(config);
35
+ // `serve` covers vitest as well as the dev server, and a test run has no page to
36
+ // watch — the marks would only change what the compiler emits under test. The
37
+ // channel turns them on from configureServer, which only a real server calls.
38
+ serving = config?.command === 'serve';
39
+ settings.sourceRoot = config.root;
40
+ },
41
+ }, enabled, start);
17
42
  }
18
43
  export default fluixi;
19
44
  // Backwards-compatible alias (matches the name fluixi has historically used).
package/dist/index.mjs CHANGED
@@ -1 +1,182 @@
1
- import{createVitePlugin as t}from"@fluixi/compiler/integrations";function e(i={}){return t(i)}var o=e;export{t as createVitePlugin,o as default,e as fluixi};
1
+ /*! @fluixi/vite-plugin v1.0.0-alpha.84 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+
3
+ // src/index.ts
4
+ import { createVitePlugin } from "@fluixi/compiler/integrations";
5
+
6
+ // src/graph-channel.ts
7
+ import { createRequire } from "node:module";
8
+ import { join } from "node:path";
9
+ var VIRTUAL = "virtual:fluixi/devtools-agent";
10
+ var RESOLVED = `\0${VIRTUAL}`;
11
+ var ENDPOINT = "/__fluixi/graph";
12
+ var EVENT = "fluixi:graph";
13
+ var MISSING = "the plugin could not load @fluixi/devtools from its own dependencies";
14
+ var WAITING = "no page has reported yet — open the application in a browser";
15
+ var INTERVAL = 100;
16
+ var HISTORY = 500;
17
+ var agentSource = (devtools, plugins, signal, reactive) => `
18
+ import { installDevtoolsHook, observeGraph } from ${JSON.stringify(devtools)};
19
+ import ${JSON.stringify(plugins)};
20
+ import { observeReactiveNodes } from ${JSON.stringify(signal)};
21
+ import { VERSION } from ${JSON.stringify(reactive)};
22
+
23
+ // The runtime this module imports is the application's own — same module graph, same nodes.
24
+ // Nothing waits for the runtime to offer itself; that path is for a tool loaded from outside.
25
+ //
26
+ // \`watch\` is this copy of devtools, handed over with the runtime. A browser extension
27
+ // installs a hook at document_start and so owns it; without this the graph would be built
28
+ // by that extension's build rather than the one shipped alongside this application.
29
+ const hook = installDevtoolsHook();
30
+ hook.inject({ observeReactiveNodes, version: VERSION, watch: observeGraph });
31
+
32
+ const send = (kind, snapshot) => import.meta.hot?.send(${JSON.stringify(EVENT)}, { kind, snapshot });
33
+
34
+ const first = hook.snapshot();
35
+ // Kept and handed back, so a browser panel polling the same hook cannot consume what this
36
+ // one has not been told about yet.
37
+ let cursor = first?.cursor;
38
+ send('full', first);
39
+ const timer = setInterval(() => {
40
+ const delta = hook.snapshot({ partial: true, since: cursor });
41
+ if (!delta) return;
42
+ cursor = delta.cursor;
43
+ // Events count on their own: an effect that ran without changing a value moves no node.
44
+ if (delta.nodes.length || delta.removed?.length || delta.events?.length) send('delta', delta);
45
+ }, ${INTERVAL});
46
+
47
+ import.meta.hot?.dispose(() => clearInterval(timer));
48
+ `;
49
+ function ownDevtools() {
50
+ try {
51
+ return createRequire(import.meta.url).resolve("@fluixi/devtools");
52
+ } catch {
53
+ return null;
54
+ }
55
+ }
56
+ function ownPlugins() {
57
+ try {
58
+ return createRequire(import.meta.url).resolve("@fluixi/devtools/plugins");
59
+ } catch {
60
+ return null;
61
+ }
62
+ }
63
+ function withGraphChannel(base, enabled, start) {
64
+ let wire = null;
65
+ let available = false;
66
+ let reason = MISSING;
67
+ let root = process.cwd();
68
+ let log;
69
+ let graph = /* @__PURE__ */ new Map();
70
+ let stamp = 0;
71
+ let events = [];
72
+ const baseResolveId = base.resolveId;
73
+ const baseTransformIndexHtml = base.transformIndexHtml;
74
+ return {
75
+ ...base,
76
+ resolveId(id, importer) {
77
+ if (id === VIRTUAL) return RESOLVED;
78
+ return baseResolveId?.call(this, id, importer) ?? null;
79
+ },
80
+ async load(id) {
81
+ if (id !== RESOLVED) return null;
82
+ const from = join(root, "fluixi-devtools-agent.js");
83
+ const specs = ["@fluixi/reactive/signal", "@fluixi/reactive"];
84
+ const ids = await Promise.all(specs.map((spec) => this.resolve?.(spec, from, { skipSelf: true })));
85
+ const missing = specs.filter((_, i) => !ids[i]?.id);
86
+ const devtools = ownDevtools();
87
+ const plugins = ownPlugins();
88
+ if (missing.length || !devtools || !plugins) {
89
+ reason = missing.length ? `${missing.join(", ")} did not resolve from ${root}` : MISSING;
90
+ log?.(`[fluixi] reactive graph off — ${reason}`);
91
+ return "export {};";
92
+ }
93
+ return agentSource(`/@fs/${devtools}`, `/@fs/${plugins}`, ids[0].id, ids[1].id);
94
+ },
95
+ async configureServer(server) {
96
+ if (!enabled()) return;
97
+ root = server.config?.root ?? root;
98
+ log = server.config?.logger?.info.bind(server.config.logger);
99
+ wire = await import("@fluixi/devtools/wire").catch(() => null);
100
+ available = wire !== null;
101
+ if (wire) start();
102
+ if (wire) reason = WAITING;
103
+ else {
104
+ log?.(`[fluixi] reactive graph off — ${MISSING}`);
105
+ }
106
+ server.middlewares.use(ENDPOINT, (_req, res) => {
107
+ const snapshot = wire ? { ...wire.serializeGraph(graph, stamp || Date.now()), events } : { t: Date.now(), nodes: [] };
108
+ const body = JSON.stringify(reason ? { ...snapshot, reason } : snapshot);
109
+ res.setHeader("Content-Type", "application/json");
110
+ res.setHeader("Access-Control-Allow-Origin", "*");
111
+ res.setHeader("Cache-Control", "no-store");
112
+ res.end(body);
113
+ });
114
+ if (!wire) return;
115
+ server.ws.on(EVENT, (payload) => {
116
+ const message = payload;
117
+ if (!message?.snapshot || !wire) return;
118
+ const full = message.kind === "full";
119
+ graph = wire.applySnapshot(full ? /* @__PURE__ */ new Map() : graph, message.snapshot);
120
+ if (full) events = [];
121
+ const arriving = message.snapshot.events;
122
+ if (arriving?.length) events = [...events, ...arriving].slice(-HISTORY);
123
+ stamp = Date.now();
124
+ reason = null;
125
+ });
126
+ },
127
+ transformIndexHtml: {
128
+ order: "pre",
129
+ handler(html, ctx) {
130
+ const inherited = callInheritedHtml(baseTransformIndexHtml, html, ctx);
131
+ if (!enabled() || !available || !wire) return inherited;
132
+ return {
133
+ html: typeof inherited === "string" ? inherited : html,
134
+ tags: [
135
+ {
136
+ tag: "script",
137
+ // First in the head, so the entry cannot create a node before the agent runs.
138
+ injectTo: "head-prepend",
139
+ attrs: { type: "module", src: `/@id/${VIRTUAL}` }
140
+ }
141
+ ]
142
+ };
143
+ }
144
+ }
145
+ };
146
+ }
147
+ function callInheritedHtml(hook, html, ctx) {
148
+ if (typeof hook === "function") return hook(html, ctx);
149
+ const handler = hook?.handler;
150
+ return handler?.(html, ctx);
151
+ }
152
+
153
+ // src/index.ts
154
+ function fluixi(options = {}) {
155
+ const settings = options;
156
+ let serving = false;
157
+ const enabled = () => serving && settings.devtools !== false;
158
+ const base = createVitePlugin(settings);
159
+ const inherited = base.configResolved;
160
+ const start = () => {
161
+ settings.sourceLocations = true;
162
+ settings.sourceLocationsExternal = typeof settings.devtools === "object" && settings.devtools.external === true;
163
+ };
164
+ return withGraphChannel(
165
+ {
166
+ ...base,
167
+ configResolved(config) {
168
+ inherited?.(config);
169
+ serving = config?.command === "serve";
170
+ settings.sourceRoot = config.root;
171
+ }
172
+ },
173
+ enabled,
174
+ start
175
+ );
176
+ }
177
+ var index_default = fluixi;
178
+ export {
179
+ createVitePlugin,
180
+ index_default as default,
181
+ fluixi
182
+ };