@mulanjs/mulanjs 1.0.1-dev.20260227135307 → 1.0.1-dev.20260227173253
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/compiler/ast-parser.d.ts +48 -0
- package/dist/compiler/ast-parser.js +54 -9
- package/dist/compiler/compiler.d.ts +9 -0
- package/dist/compiler/compiler.js +45 -2
- package/dist/compiler/dom-compiler.d.ts +7 -0
- package/dist/compiler/dom-compiler.js +90 -33
- package/dist/compiler/script-compiler.d.ts +11 -0
- package/dist/compiler/script-compiler.js +108 -116
- package/dist/compiler/sfc-parser.d.ts +21 -0
- package/dist/compiler/ssr-compiler.d.ts +7 -0
- package/dist/compiler/ssr-compiler.js +142 -0
- package/dist/compiler/style-compiler.d.ts +8 -0
- package/dist/compiler/template-compiler.d.ts +8 -0
- package/dist/components/bloch-sphere.js +9 -3
- package/dist/components/infinity-list.js +7 -1
- package/dist/core/component.js +66 -15
- package/dist/core/hooks.js +53 -29
- package/dist/core/quantum.js +30 -17
- package/dist/core/query.js +11 -6
- package/dist/core/reactive.js +88 -7
- package/dist/core/renderer.js +9 -8
- package/dist/core/ssr.js +50 -0
- package/dist/core/surge.js +7 -2
- package/dist/core/vault.js +9 -5
- package/dist/index.js +63 -27
- package/dist/mulan.esm.js +187 -19
- package/dist/mulan.esm.js.map +1 -1
- package/dist/mulan.js +1890 -1590
- package/dist/mulan.js.map +1 -1
- package/dist/router/index.js +17 -10
- package/dist/security/sanitizer.js +5 -1
- package/dist/store/index.js +9 -5
- package/dist/types/ast-parser.d.ts +2 -0
- package/dist/types/compiler/ast-parser.d.ts +2 -0
- package/dist/types/compiler/compiler.d.ts +1 -0
- package/dist/types/compiler/ssr-compiler.d.ts +7 -0
- package/dist/types/compiler.d.ts +1 -0
- package/dist/types/components/bloch-sphere.d.ts +3 -1
- package/dist/types/components/infinity-list.d.ts +3 -1
- package/dist/types/core/component.d.ts +14 -0
- package/dist/types/core/reactive.d.ts +5 -1
- package/dist/types/core/renderer.d.ts +0 -1
- package/dist/types/core/ssr.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/ssr-compiler.d.ts +7 -0
- package/package.json +1 -1
- package/src/compiler/ast-parser.ts +62 -10
- package/src/compiler/compiler.ts +46 -1
- package/src/compiler/dom-compiler.ts +100 -34
- package/src/compiler/script-compiler.ts +117 -126
- package/src/compiler/ssr-compiler.ts +157 -0
- package/src/loader/index.js +12 -19
package/dist/core/hooks.js
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.muHistory = exports.onMuPanic = exports.muThrottled = exports.muDebounced = exports.onMuVisibility = exports.muSuspense = exports.muVault = exports.muPulse = exports.muGeom = exports.onMuVoice = exports.onMuShake = exports.onMuResume = exports.onMuIdle = exports.onMuDestroy = exports.onMuMount = exports.onMuInit = exports.muEffect = exports.muMemo = exports.muState = exports.getCurrentInstance = exports.setCurrentInstance = void 0;
|
|
4
|
+
const reactive_1 = require("./reactive");
|
|
5
|
+
const vault_1 = require("./vault");
|
|
3
6
|
// Global context to track the current component instance
|
|
4
7
|
let currentInstance = null;
|
|
5
|
-
|
|
8
|
+
function setCurrentInstance(instance) {
|
|
6
9
|
currentInstance = instance;
|
|
7
10
|
}
|
|
8
|
-
|
|
11
|
+
exports.setCurrentInstance = setCurrentInstance;
|
|
12
|
+
function getCurrentInstance() {
|
|
9
13
|
return currentInstance;
|
|
10
14
|
}
|
|
15
|
+
exports.getCurrentInstance = getCurrentInstance;
|
|
11
16
|
// --- Mulan Unique Reactivity Hooks ---
|
|
12
|
-
|
|
17
|
+
function muState(initialValue) {
|
|
13
18
|
if (typeof initialValue === 'object' && initialValue !== null) {
|
|
14
|
-
return reactive(initialValue);
|
|
19
|
+
return (0, reactive_1.reactive)(initialValue);
|
|
15
20
|
}
|
|
16
21
|
// Core reactive state container for primitives
|
|
17
|
-
return reactive({ value: initialValue });
|
|
22
|
+
return (0, reactive_1.reactive)({ value: initialValue });
|
|
18
23
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
24
|
+
exports.muState = muState;
|
|
25
|
+
function muMemo(computeFn) {
|
|
26
|
+
const signal = (0, reactive_1.reactive)({ value: undefined });
|
|
27
|
+
const stop = (0, reactive_1.effect)(() => {
|
|
22
28
|
signal.value = computeFn();
|
|
23
29
|
});
|
|
24
30
|
const instance = getCurrentInstance();
|
|
@@ -29,8 +35,9 @@ export function muMemo(computeFn) {
|
|
|
29
35
|
}
|
|
30
36
|
return signal;
|
|
31
37
|
}
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
exports.muMemo = muMemo;
|
|
39
|
+
function muEffect(fn) {
|
|
40
|
+
const stop = (0, reactive_1.effect)(fn);
|
|
34
41
|
const instance = getCurrentInstance();
|
|
35
42
|
if (instance) {
|
|
36
43
|
if (!instance._effects)
|
|
@@ -38,8 +45,9 @@ export function muEffect(fn) {
|
|
|
38
45
|
instance._effects.push(stop);
|
|
39
46
|
}
|
|
40
47
|
}
|
|
48
|
+
exports.muEffect = muEffect;
|
|
41
49
|
// --- The "Mulan Cycle" (Lifecycle) ---
|
|
42
|
-
|
|
50
|
+
function onMuInit(fn) {
|
|
43
51
|
const instance = getCurrentInstance();
|
|
44
52
|
if (instance) {
|
|
45
53
|
if (!instance._hooks)
|
|
@@ -52,7 +60,8 @@ export function onMuInit(fn) {
|
|
|
52
60
|
console.warn('onMuInit called outside of component setup context.');
|
|
53
61
|
}
|
|
54
62
|
}
|
|
55
|
-
|
|
63
|
+
exports.onMuInit = onMuInit;
|
|
64
|
+
function onMuMount(fn) {
|
|
56
65
|
// New hook for when component is actually in DOM (simulated for now via update)
|
|
57
66
|
const instance = getCurrentInstance();
|
|
58
67
|
if (instance) {
|
|
@@ -63,7 +72,8 @@ export function onMuMount(fn) {
|
|
|
63
72
|
instance._hooks.onMuMount.push(fn);
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
|
-
|
|
75
|
+
exports.onMuMount = onMuMount;
|
|
76
|
+
function onMuDestroy(fn) {
|
|
67
77
|
const instance = getCurrentInstance();
|
|
68
78
|
if (instance) {
|
|
69
79
|
if (!instance._hooks)
|
|
@@ -73,11 +83,12 @@ export function onMuDestroy(fn) {
|
|
|
73
83
|
instance._hooks.onMuDestroy.push(fn);
|
|
74
84
|
}
|
|
75
85
|
}
|
|
86
|
+
exports.onMuDestroy = onMuDestroy;
|
|
76
87
|
/**
|
|
77
88
|
* onMuIdle - The "Environment Life" Hook.
|
|
78
89
|
* Executes heavy logic ONLY when the browser is taking a nap (idle).
|
|
79
90
|
*/
|
|
80
|
-
|
|
91
|
+
function onMuIdle(fn) {
|
|
81
92
|
const instance = getCurrentInstance();
|
|
82
93
|
// Polyfill for Safari/Old Browsers
|
|
83
94
|
const requestIdleCallback = window.requestIdleCallback || function (cb) {
|
|
@@ -101,12 +112,13 @@ export function onMuIdle(fn) {
|
|
|
101
112
|
});
|
|
102
113
|
}
|
|
103
114
|
}
|
|
115
|
+
exports.onMuIdle = onMuIdle;
|
|
104
116
|
/**
|
|
105
117
|
* onMuResume - The "Tab Life" Hook.
|
|
106
118
|
* Executes when the user switches BACK to this tab.
|
|
107
119
|
* Perfect for refreshing data or resuming animations to save battery.
|
|
108
120
|
*/
|
|
109
|
-
|
|
121
|
+
function onMuResume(fn) {
|
|
110
122
|
const handler = () => {
|
|
111
123
|
if (document.visibilityState === 'visible') {
|
|
112
124
|
fn();
|
|
@@ -115,12 +127,13 @@ export function onMuResume(fn) {
|
|
|
115
127
|
document.addEventListener('visibilitychange', handler);
|
|
116
128
|
onMuDestroy(() => document.removeEventListener('visibilitychange', handler));
|
|
117
129
|
}
|
|
130
|
+
exports.onMuResume = onMuResume;
|
|
118
131
|
/**
|
|
119
132
|
* onMuShake - The "Physical Life" Hook.
|
|
120
133
|
* Executes when the device is shaken.
|
|
121
134
|
* Usage: Undo, Refresh, or "Rage Quit" easter eggs.
|
|
122
135
|
*/
|
|
123
|
-
|
|
136
|
+
function onMuShake(fn) {
|
|
124
137
|
// Threshold for shake detection
|
|
125
138
|
const threshold = 15;
|
|
126
139
|
let lastX = 0, lastY = 0, lastZ = 0;
|
|
@@ -153,13 +166,14 @@ export function onMuShake(fn) {
|
|
|
153
166
|
console.warn("[MulanJS] Device Motion not supported on this device.");
|
|
154
167
|
}
|
|
155
168
|
}
|
|
169
|
+
exports.onMuShake = onMuShake;
|
|
156
170
|
/**
|
|
157
171
|
* onMuVoice - The "Sound Life" Hook.
|
|
158
172
|
* Executes when a specific word is spoken.
|
|
159
173
|
* @param command The word to listen for (e.g., "save", "next")
|
|
160
174
|
* @param fn The action to take
|
|
161
175
|
*/
|
|
162
|
-
|
|
176
|
+
function onMuVoice(command, fn) {
|
|
163
177
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
164
178
|
if (!SpeechRecognition) {
|
|
165
179
|
console.warn("[MulanJS] Voice Control (Web Speech API) not supported in this browser.");
|
|
@@ -188,11 +202,12 @@ export function onMuVoice(command, fn) {
|
|
|
188
202
|
recognition.stop();
|
|
189
203
|
});
|
|
190
204
|
}
|
|
205
|
+
exports.onMuVoice = onMuVoice;
|
|
191
206
|
// --- "Outside The Box" Hooks (Mulan Exclusives) ---
|
|
192
207
|
/**
|
|
193
208
|
* muGeom - Tracks window or element dimensions reactively.
|
|
194
209
|
*/
|
|
195
|
-
|
|
210
|
+
function muGeom() {
|
|
196
211
|
const dims = muState({ width: window.innerWidth, height: window.innerHeight });
|
|
197
212
|
const handler = () => {
|
|
198
213
|
dims.width = window.innerWidth;
|
|
@@ -205,10 +220,11 @@ export function muGeom() {
|
|
|
205
220
|
});
|
|
206
221
|
return dims;
|
|
207
222
|
}
|
|
223
|
+
exports.muGeom = muGeom;
|
|
208
224
|
/**
|
|
209
225
|
* muPulse - Reactive network status.
|
|
210
226
|
*/
|
|
211
|
-
|
|
227
|
+
function muPulse() {
|
|
212
228
|
const status = muState({ online: navigator.onLine });
|
|
213
229
|
const setOnline = () => status.online = true;
|
|
214
230
|
const setOffline = () => status.online = false;
|
|
@@ -220,19 +236,21 @@ export function muPulse() {
|
|
|
220
236
|
});
|
|
221
237
|
return status;
|
|
222
238
|
}
|
|
239
|
+
exports.muPulse = muPulse;
|
|
223
240
|
/**
|
|
224
241
|
* muVault - Secure reactive LocalStorage wrapper.
|
|
225
242
|
* Powered by the Iron Fortress persistent primitive.
|
|
226
243
|
*/
|
|
227
|
-
|
|
228
|
-
return persistent(key, initial, Object.assign(Object.assign({}, options), { onCleanup: (fn) => onMuDestroy(fn) }));
|
|
244
|
+
function muVault(key, initial, options = {}) {
|
|
245
|
+
return (0, vault_1.persistent)(key, initial, Object.assign(Object.assign({}, options), { onCleanup: (fn) => onMuDestroy(fn) }));
|
|
229
246
|
}
|
|
247
|
+
exports.muVault = muVault;
|
|
230
248
|
// --- Next-Gen MulanJS Hooks ---
|
|
231
249
|
/**
|
|
232
250
|
* muSuspense - The Asynchronous Barrier.
|
|
233
251
|
* Natively handles async state (loading/data/error) without wrapper components.
|
|
234
252
|
*/
|
|
235
|
-
|
|
253
|
+
function muSuspense(promiseFn) {
|
|
236
254
|
const state = muState({
|
|
237
255
|
loading: true,
|
|
238
256
|
data: null,
|
|
@@ -250,11 +268,12 @@ export function muSuspense(promiseFn) {
|
|
|
250
268
|
});
|
|
251
269
|
return state;
|
|
252
270
|
}
|
|
271
|
+
exports.muSuspense = muSuspense;
|
|
253
272
|
/**
|
|
254
273
|
* onMuVisibility - The Intersection Observer Hook.
|
|
255
274
|
* Triggers when the component enters/leaves the viewport.
|
|
256
275
|
*/
|
|
257
|
-
|
|
276
|
+
function onMuVisibility(callback, options = { threshold: 0.1 }) {
|
|
258
277
|
const instance = getCurrentInstance();
|
|
259
278
|
// We defer observation to mount phase to ensure DOM exists
|
|
260
279
|
onMuMount(() => {
|
|
@@ -271,10 +290,11 @@ export function onMuVisibility(callback, options = { threshold: 0.1 }) {
|
|
|
271
290
|
});
|
|
272
291
|
});
|
|
273
292
|
}
|
|
293
|
+
exports.onMuVisibility = onMuVisibility;
|
|
274
294
|
/**
|
|
275
295
|
* muDebounced - High-performance debouncing built directly into a reactive signal.
|
|
276
296
|
*/
|
|
277
|
-
|
|
297
|
+
function muDebounced(initialValue, delayMs) {
|
|
278
298
|
const state = muState(initialValue);
|
|
279
299
|
let timeoutId;
|
|
280
300
|
return {
|
|
@@ -289,10 +309,11 @@ export function muDebounced(initialValue, delayMs) {
|
|
|
289
309
|
}
|
|
290
310
|
};
|
|
291
311
|
}
|
|
312
|
+
exports.muDebounced = muDebounced;
|
|
292
313
|
/**
|
|
293
314
|
* muThrottled - High-performance throttling built directly into a reactive signal.
|
|
294
315
|
*/
|
|
295
|
-
|
|
316
|
+
function muThrottled(initialValue, delayMs) {
|
|
296
317
|
const state = muState(initialValue);
|
|
297
318
|
let lastRan = 0;
|
|
298
319
|
return {
|
|
@@ -308,11 +329,12 @@ export function muThrottled(initialValue, delayMs) {
|
|
|
308
329
|
}
|
|
309
330
|
};
|
|
310
331
|
}
|
|
332
|
+
exports.muThrottled = muThrottled;
|
|
311
333
|
/**
|
|
312
334
|
* onMuPanic - The Iron Fortress Error Boundary.
|
|
313
335
|
* Catches unhandled exceptions within the component scope.
|
|
314
336
|
*/
|
|
315
|
-
|
|
337
|
+
function onMuPanic(fallbackFn) {
|
|
316
338
|
const instance = getCurrentInstance();
|
|
317
339
|
const handler = (event) => {
|
|
318
340
|
// Broad catch - in a full implementation, we'd inspect the stack trace
|
|
@@ -331,10 +353,11 @@ export function onMuPanic(fallbackFn) {
|
|
|
331
353
|
window.removeEventListener('unhandledrejection', handler);
|
|
332
354
|
});
|
|
333
355
|
}
|
|
356
|
+
exports.onMuPanic = onMuPanic;
|
|
334
357
|
/**
|
|
335
358
|
* muHistory - State with built-in Undo/Redo tracking.
|
|
336
359
|
*/
|
|
337
|
-
|
|
360
|
+
function muHistory(initialValue) {
|
|
338
361
|
const state = muState(initialValue);
|
|
339
362
|
// Explicit wrapper object because muState treats bare arrays dynamically
|
|
340
363
|
const historyTracker = muState({ log: [initialValue] });
|
|
@@ -369,3 +392,4 @@ export function muHistory(initialValue) {
|
|
|
369
392
|
get future() { return historyTracker.log.slice(pointer.value + 1); }
|
|
370
393
|
};
|
|
371
394
|
}
|
|
395
|
+
exports.muHistory = muHistory;
|
package/dist/core/quantum.js
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.muSwitch = exports.muControl = exports.muParallel = exports.muMeasure = exports.muTeleport = exports.muEntangle = exports.muSearch = exports.muGate = exports.muQubit = exports.muRegister = exports.activeControls = void 0;
|
|
4
|
+
const hooks_1 = require("./hooks");
|
|
2
5
|
/**
|
|
3
6
|
* Mulan Quantum (ASTR-Q+) Core
|
|
4
7
|
* Advanced Simulation Engine for multi-qubit registers and entanglement.
|
|
5
8
|
*/
|
|
6
9
|
// -- GLOBAL CONTEXT FOR QUANTUM CONTROL --
|
|
7
10
|
// Defined at top to ensure visibility for muGate
|
|
8
|
-
|
|
11
|
+
exports.activeControls = [];
|
|
9
12
|
/**
|
|
10
13
|
* Creates a quantum register of size n.
|
|
11
14
|
* State vector will have 2^n amplitudes.
|
|
12
15
|
*/
|
|
13
|
-
|
|
16
|
+
function muRegister(n) {
|
|
14
17
|
const numStates = Math.pow(2, n);
|
|
15
18
|
const amplitudes = new Array(numStates).fill(0).map((_, i) => ({
|
|
16
19
|
re: i === 0 ? 1 : 0,
|
|
17
20
|
im: 0
|
|
18
21
|
}));
|
|
19
|
-
return muState({
|
|
22
|
+
return (0, hooks_1.muState)({
|
|
20
23
|
value: {
|
|
21
24
|
size: n,
|
|
22
25
|
amplitudes
|
|
23
26
|
}
|
|
24
27
|
});
|
|
25
28
|
}
|
|
29
|
+
exports.muRegister = muRegister;
|
|
26
30
|
/**
|
|
27
31
|
* Backward compatible muQubit (Single Qubit Register)
|
|
28
32
|
*/
|
|
29
|
-
|
|
33
|
+
function muQubit(initial = 0) {
|
|
30
34
|
const q = muRegister(1);
|
|
31
35
|
if (initial === 1) {
|
|
32
36
|
muGate(q, 'X', 0);
|
|
@@ -37,6 +41,7 @@ export function muQubit(initial = 0) {
|
|
|
37
41
|
Object.defineProperty(q.value, 'beta', { get: () => q.value.amplitudes[1] });
|
|
38
42
|
return q;
|
|
39
43
|
}
|
|
44
|
+
exports.muQubit = muQubit;
|
|
40
45
|
/**
|
|
41
46
|
* Internal helper to update register state while maintaining compatibility
|
|
42
47
|
*/
|
|
@@ -56,13 +61,13 @@ function updateState(reg, newState) {
|
|
|
56
61
|
}
|
|
57
62
|
reg.value = newState;
|
|
58
63
|
}
|
|
59
|
-
|
|
64
|
+
function muGate(reg, type, target = 0, control) {
|
|
60
65
|
const state = reg.value;
|
|
61
66
|
const n = state.size;
|
|
62
67
|
const amplitudes = state.amplitudes;
|
|
63
68
|
const newAmps = amplitudes.map(a => (Object.assign({}, a)));
|
|
64
69
|
// Prepare Effective Control (Explicit Arguments + Global Context)
|
|
65
|
-
const effectiveControl = [...(control === undefined ? [] : (Array.isArray(control) ? control : [control])), ...activeControls];
|
|
70
|
+
const effectiveControl = [...(control === undefined ? [] : (Array.isArray(control) ? control : [control])), ...exports.activeControls];
|
|
66
71
|
// Helper: Check if all control bits are 1
|
|
67
72
|
const checkControl = (index, ctrl) => {
|
|
68
73
|
if (ctrl === undefined || (Array.isArray(ctrl) && ctrl.length === 0))
|
|
@@ -77,7 +82,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
77
82
|
// Iterate only half to avoid double swapping
|
|
78
83
|
for (let i = 0; i < amplitudes.length; i++) {
|
|
79
84
|
// Check active controls for SWAP too
|
|
80
|
-
if (activeControls.length > 0 && !checkControl(i, activeControls))
|
|
85
|
+
if (exports.activeControls.length > 0 && !checkControl(i, exports.activeControls))
|
|
81
86
|
continue;
|
|
82
87
|
const bit1 = (i >> t1) & 1;
|
|
83
88
|
const bit2 = (i >> t2) & 1;
|
|
@@ -167,6 +172,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
167
172
|
}
|
|
168
173
|
updateState(reg, Object.assign(Object.assign({}, state), { amplitudes: newAmps }));
|
|
169
174
|
}
|
|
175
|
+
exports.muGate = muGate;
|
|
170
176
|
/**
|
|
171
177
|
* Mulan Search Logic (Grover's Operator)
|
|
172
178
|
* Automatically constructs a multi-controlled Phase Flip (Z) for a specific target state.
|
|
@@ -174,7 +180,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
174
180
|
* @param reg Quantum Register
|
|
175
181
|
* @param targetState The integer state to "search" and mark (e.g. 2 for |10>)
|
|
176
182
|
*/
|
|
177
|
-
|
|
183
|
+
function muSearch(reg, targetState) {
|
|
178
184
|
const n = reg.value.size;
|
|
179
185
|
const controls = [];
|
|
180
186
|
// 1. Identify which bits are 0 and need wrapping with X gates
|
|
@@ -225,10 +231,12 @@ export function muSearch(reg, targetState) {
|
|
|
225
231
|
for (let i = 0; i < n; i++)
|
|
226
232
|
muGate(reg, 'H', i);
|
|
227
233
|
}
|
|
228
|
-
|
|
234
|
+
exports.muSearch = muSearch;
|
|
235
|
+
function muEntangle(reg, i, j) {
|
|
229
236
|
muGate(reg, 'H', i);
|
|
230
237
|
muGate(reg, 'CNOT', j, i);
|
|
231
238
|
}
|
|
239
|
+
exports.muEntangle = muEntangle;
|
|
232
240
|
/**
|
|
233
241
|
* Quantum Teleportation Protocol
|
|
234
242
|
* Transfers the state of `msgIdx` to `targetIdx` using `ancillaIdx` as a resource.
|
|
@@ -237,7 +245,7 @@ export function muEntangle(reg, i, j) {
|
|
|
237
245
|
* @param ancillaIdx The helper qubit (Alice's half of entanglement)
|
|
238
246
|
* @param targetIdx The destination qubit (Bob)
|
|
239
247
|
*/
|
|
240
|
-
|
|
248
|
+
function muTeleport(reg, msgIdx, ancillaIdx, targetIdx) {
|
|
241
249
|
// 1. Create Bell Pair (Entanglement) between Ancilla and Target
|
|
242
250
|
// Represents the shared link between Alice and Bob
|
|
243
251
|
muEntangle(reg, ancillaIdx, targetIdx);
|
|
@@ -254,13 +262,14 @@ export function muTeleport(reg, msgIdx, ancillaIdx, targetIdx) {
|
|
|
254
262
|
if (m1 === 1)
|
|
255
263
|
muGate(reg, 'Z', targetIdx);
|
|
256
264
|
}
|
|
265
|
+
exports.muTeleport = muTeleport;
|
|
257
266
|
/**
|
|
258
267
|
* Measures a specific qubit in the register, collapsing the superposition.
|
|
259
268
|
* @param reg Quantum Register
|
|
260
269
|
* @param target Index of qubit to measure
|
|
261
270
|
* @returns 0 or 1
|
|
262
271
|
*/
|
|
263
|
-
|
|
272
|
+
function muMeasure(reg, target = 0) {
|
|
264
273
|
const state = reg.value;
|
|
265
274
|
const amplitudes = state.amplitudes;
|
|
266
275
|
let prob0 = 0;
|
|
@@ -292,6 +301,7 @@ export function muMeasure(reg, target = 0) {
|
|
|
292
301
|
updateState(reg, Object.assign(Object.assign({}, state), { amplitudes: newAmps }));
|
|
293
302
|
return result;
|
|
294
303
|
}
|
|
304
|
+
exports.muMeasure = muMeasure;
|
|
295
305
|
/**
|
|
296
306
|
* Quantum Loop: Parallel Execution
|
|
297
307
|
* Applies a gate to multiple qubits "simultaneously" (in simulation steps).
|
|
@@ -300,7 +310,7 @@ export function muMeasure(reg, target = 0) {
|
|
|
300
310
|
* @param qubits Array of qubit indices
|
|
301
311
|
* @param gate Gate type to apply (e.g. 'H', 'X')
|
|
302
312
|
*/
|
|
303
|
-
|
|
313
|
+
function muParallel(reg, qubits, gate) {
|
|
304
314
|
if (gate === 'SWAP') {
|
|
305
315
|
throw new Error("SWAP cannot be applied in parallel (requires pairs).");
|
|
306
316
|
}
|
|
@@ -308,27 +318,29 @@ export function muParallel(reg, qubits, gate) {
|
|
|
308
318
|
// Here, we loop, but logical time is constant.
|
|
309
319
|
qubits.forEach(q => muGate(reg, gate, q));
|
|
310
320
|
}
|
|
321
|
+
exports.muParallel = muParallel;
|
|
311
322
|
/**
|
|
312
323
|
* Applies a block of operations controlled by specific qubits.
|
|
313
324
|
* Enables "Quantum If/Else".
|
|
314
325
|
*/
|
|
315
|
-
|
|
326
|
+
function muControl(reg, controlQubit, inverse, block) {
|
|
316
327
|
// 1. Setup Context
|
|
317
328
|
if (inverse) {
|
|
318
329
|
muGate(reg, 'X', controlQubit); // Flip 0 to 1 to activate
|
|
319
330
|
}
|
|
320
|
-
activeControls.push(controlQubit);
|
|
331
|
+
exports.activeControls.push(controlQubit);
|
|
321
332
|
try {
|
|
322
333
|
block();
|
|
323
334
|
}
|
|
324
335
|
finally {
|
|
325
|
-
activeControls.pop();
|
|
336
|
+
exports.activeControls.pop();
|
|
326
337
|
// Uncompute (Restore 0)
|
|
327
338
|
if (inverse) {
|
|
328
339
|
muGate(reg, 'X', controlQubit);
|
|
329
340
|
}
|
|
330
341
|
}
|
|
331
342
|
}
|
|
343
|
+
exports.muControl = muControl;
|
|
332
344
|
/**
|
|
333
345
|
* Quantum Switch: conditional Logic on Superposition
|
|
334
346
|
* Executes different logic branches based on the state of control qubits.
|
|
@@ -339,7 +351,7 @@ export function muControl(reg, controlQubit, inverse, block) {
|
|
|
339
351
|
* @param controlQubit The qubit controlling the switch (Single control for v1)
|
|
340
352
|
* @param cases Object mapping state (0 or 1) to a function executing quantum operations
|
|
341
353
|
*/
|
|
342
|
-
|
|
354
|
+
function muSwitch(reg, controlQubit, cases) {
|
|
343
355
|
if (cases[0]) {
|
|
344
356
|
muControl(reg, controlQubit, true, cases[0]);
|
|
345
357
|
}
|
|
@@ -347,3 +359,4 @@ export function muSwitch(reg, controlQubit, cases) {
|
|
|
347
359
|
muControl(reg, controlQubit, false, cases[1]);
|
|
348
360
|
}
|
|
349
361
|
}
|
|
362
|
+
exports.muSwitch = muSwitch;
|
package/dist/core/query.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -7,9 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
9
|
});
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.useMutation = exports.useQuery = void 0;
|
|
13
|
+
const reactive_1 = require("./reactive");
|
|
14
|
+
function useQuery(queryFn, options = { enabled: true }) {
|
|
15
|
+
const state = (0, reactive_1.reactive)({
|
|
13
16
|
data: null,
|
|
14
17
|
isLoading: false,
|
|
15
18
|
error: null
|
|
@@ -30,7 +33,7 @@ export function useQuery(queryFn, options = { enabled: true }) {
|
|
|
30
33
|
});
|
|
31
34
|
if (options.enabled) {
|
|
32
35
|
// Run automatically
|
|
33
|
-
effect(() => {
|
|
36
|
+
(0, reactive_1.effect)(() => {
|
|
34
37
|
// Basic effect wrapper to allow reactivity if queryFn relies on signals
|
|
35
38
|
execute();
|
|
36
39
|
});
|
|
@@ -42,8 +45,9 @@ export function useQuery(queryFn, options = { enabled: true }) {
|
|
|
42
45
|
refetch: execute
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
exports.useQuery = useQuery;
|
|
49
|
+
function useMutation(mutationFn) {
|
|
50
|
+
const state = (0, reactive_1.reactive)({
|
|
47
51
|
data: null,
|
|
48
52
|
isLoading: false,
|
|
49
53
|
error: null
|
|
@@ -71,3 +75,4 @@ export function useMutation(mutationFn) {
|
|
|
71
75
|
mutate
|
|
72
76
|
};
|
|
73
77
|
}
|
|
78
|
+
exports.useMutation = useMutation;
|
package/dist/core/reactive.js
CHANGED
|
@@ -1,10 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// MulanJS 2.0: Signal-Powered Reactivity Engine
|
|
2
3
|
// "Compatible Surface, World-Class Engine"
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.ref = exports.reactive = exports.effect = exports.Signal = exports.nextTick = exports.queueEffect = void 0;
|
|
3
6
|
let activeEffect = null;
|
|
4
7
|
let activeEffectRunner = null;
|
|
5
8
|
const targetMap = new WeakMap();
|
|
9
|
+
// --- Mulan Quantum Scheduler (Time-Slicing) ---
|
|
10
|
+
// Assign unique IDs to effects for basic topological sorting (lower IDs run first)
|
|
11
|
+
let effectIdCounter = 0;
|
|
12
|
+
const pendingEffects = new Set();
|
|
13
|
+
let isScheduling = false;
|
|
14
|
+
const TIME_BUDGET = 8; // 8ms frame budget for 60FPS lock
|
|
15
|
+
function runScheduler() {
|
|
16
|
+
if (pendingEffects.size === 0) {
|
|
17
|
+
isScheduling = false;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const start = typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
21
|
+
// Convert to array and sort to ensure parent effects run before children (Topological Push-Pull approximation)
|
|
22
|
+
const sortedEffects = Array.from(pendingEffects).sort((a, b) => {
|
|
23
|
+
return (a._id || 0) - (b._id || 0);
|
|
24
|
+
});
|
|
25
|
+
for (const fn of sortedEffects) {
|
|
26
|
+
pendingEffects.delete(fn);
|
|
27
|
+
fn();
|
|
28
|
+
const now = typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
29
|
+
if (now - start > TIME_BUDGET) {
|
|
30
|
+
break; // Yield to browser
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (pendingEffects.size > 0) {
|
|
34
|
+
if (typeof MessageChannel !== 'undefined') {
|
|
35
|
+
const channel = new MessageChannel();
|
|
36
|
+
channel.port1.onmessage = runScheduler;
|
|
37
|
+
channel.port2.postMessage(null);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
setTimeout(runScheduler, 0);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
isScheduling = false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function queueEffect(fn) {
|
|
48
|
+
pendingEffects.add(fn);
|
|
49
|
+
if (!isScheduling) {
|
|
50
|
+
isScheduling = true;
|
|
51
|
+
if (typeof Promise !== 'undefined') {
|
|
52
|
+
Promise.resolve().then(runScheduler);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
setTimeout(runScheduler, 0);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.queueEffect = queueEffect;
|
|
60
|
+
function nextTick() {
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
}
|
|
63
|
+
exports.nextTick = nextTick;
|
|
6
64
|
// --- Signal Core (The Engine) ---
|
|
7
|
-
|
|
65
|
+
class Signal {
|
|
8
66
|
constructor(initialValue) {
|
|
9
67
|
this._subscribers = new Set();
|
|
10
68
|
this._value = initialValue;
|
|
@@ -22,17 +80,26 @@ export class Signal {
|
|
|
22
80
|
}
|
|
23
81
|
}
|
|
24
82
|
notify() {
|
|
25
|
-
this._subscribers.forEach(fn =>
|
|
83
|
+
this._subscribers.forEach(fn => {
|
|
84
|
+
if (fn._sync) {
|
|
85
|
+
fn();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
queueEffect(fn);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
26
91
|
}
|
|
27
92
|
}
|
|
93
|
+
exports.Signal = Signal;
|
|
28
94
|
// --- Compatibility Layer (The Surface) ---
|
|
29
|
-
|
|
95
|
+
function effect(fn, targetNode, options = {}) {
|
|
30
96
|
let stopped = false;
|
|
97
|
+
const id = ++effectIdCounter;
|
|
31
98
|
const run = () => {
|
|
32
99
|
if (stopped)
|
|
33
100
|
return;
|
|
34
101
|
const prevRunner = activeEffectRunner;
|
|
35
|
-
activeEffectRunner = { run, node: targetNode };
|
|
102
|
+
activeEffectRunner = { run, node: targetNode, id };
|
|
36
103
|
try {
|
|
37
104
|
fn();
|
|
38
105
|
}
|
|
@@ -40,11 +107,16 @@ export function effect(fn, targetNode) {
|
|
|
40
107
|
activeEffectRunner = prevRunner;
|
|
41
108
|
}
|
|
42
109
|
};
|
|
110
|
+
// Attach ID for topological sorting
|
|
111
|
+
run._id = id;
|
|
112
|
+
run._sync = options.sync;
|
|
43
113
|
run();
|
|
44
114
|
return () => {
|
|
45
115
|
stopped = true;
|
|
116
|
+
pendingEffects.delete(run);
|
|
46
117
|
};
|
|
47
118
|
}
|
|
119
|
+
exports.effect = effect;
|
|
48
120
|
function track(target, key) {
|
|
49
121
|
if (activeEffectRunner) {
|
|
50
122
|
let depsMap = targetMap.get(target);
|
|
@@ -64,14 +136,21 @@ function trigger(target, key) {
|
|
|
64
136
|
return;
|
|
65
137
|
const dep = depsMap.get(key);
|
|
66
138
|
if (dep) {
|
|
67
|
-
dep.forEach((fn) =>
|
|
139
|
+
dep.forEach((fn) => {
|
|
140
|
+
if (fn._sync) {
|
|
141
|
+
fn(); // Run synchronously if explicitly requested (e.g. for muMemo)
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
queueEffect(fn); // Push to Quantum Scheduler
|
|
145
|
+
}
|
|
146
|
+
});
|
|
68
147
|
}
|
|
69
148
|
}
|
|
70
149
|
/**
|
|
71
150
|
* Creates a reactive proxy object (Vue-compatible).
|
|
72
151
|
* Now optimized to respect Mulan Cycle.
|
|
73
152
|
*/
|
|
74
|
-
|
|
153
|
+
function reactive(target) {
|
|
75
154
|
return new Proxy(target, {
|
|
76
155
|
get(obj, prop, receiver) {
|
|
77
156
|
// IRON FORTRESS: Prototype Pollution Protection (Read)
|
|
@@ -97,10 +176,12 @@ export function reactive(target) {
|
|
|
97
176
|
},
|
|
98
177
|
});
|
|
99
178
|
}
|
|
179
|
+
exports.reactive = reactive;
|
|
100
180
|
/**
|
|
101
181
|
* Creates a standalone reactive reference.
|
|
102
182
|
* Backed by the Mulan Signal Engine.
|
|
103
183
|
*/
|
|
104
|
-
|
|
184
|
+
function ref(value) {
|
|
105
185
|
return new Signal(value);
|
|
106
186
|
}
|
|
187
|
+
exports.ref = ref;
|
package/dist/core/renderer.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitize = exports.hydrate = exports.render = void 0;
|
|
4
|
+
function render(template, container) {
|
|
2
5
|
// Focus Preservation (The "Mulan Glance" Technique)
|
|
3
6
|
let focusedId = null;
|
|
4
7
|
let selectionStart = null;
|
|
@@ -81,7 +84,8 @@ export function render(template, container) {
|
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
|
-
|
|
87
|
+
exports.render = render;
|
|
88
|
+
function hydrate(template, container) {
|
|
85
89
|
// In a string-based framework, hydration is often just "take over".
|
|
86
90
|
// For now, we'll verify if the server content matches (simple check)
|
|
87
91
|
// and then assume control. In a more advanced version, we'd attach listeners without re-rendering.
|
|
@@ -100,12 +104,8 @@ export function hydrate(template, container) {
|
|
|
100
104
|
}
|
|
101
105
|
// Future: Attach event listeners here if we had a mechanism for it.
|
|
102
106
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
// Can include additional sanitization or metadata injection here.
|
|
106
|
-
return template;
|
|
107
|
-
}
|
|
108
|
-
export function sanitize(str) {
|
|
107
|
+
exports.hydrate = hydrate;
|
|
108
|
+
function sanitize(str) {
|
|
109
109
|
// Check if we are in a browser environment
|
|
110
110
|
if (typeof document !== 'undefined') {
|
|
111
111
|
const temp = document.createElement('div');
|
|
@@ -119,3 +119,4 @@ export function sanitize(str) {
|
|
|
119
119
|
.replace(/"/g, """)
|
|
120
120
|
.replace(/'/g, "'");
|
|
121
121
|
}
|
|
122
|
+
exports.sanitize = sanitize;
|