@mulanjs/mulanjs 1.0.1-dev.20260219221500 → 1.0.1-dev.20260220121828
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/README.md +4 -2
- package/dist/compiler/compiler.js +81 -4
- package/dist/compiler/script-compiler.js +158 -21
- package/dist/compiler/style-compiler.js +61 -4
- package/dist/compiler/template-compiler.js +44 -4
- package/dist/core/quantum.js +74 -9
- package/dist/core/query.js +12 -2
- package/dist/core/surge.js +92 -0
- package/dist/core/vault.js +6 -25
- package/dist/index.js +4 -2
- package/dist/mulan.esm.js +225 -43
- package/dist/mulan.js +14 -4
- package/dist/types/compiler/compiler.d.ts +2 -1
- package/dist/types/compiler/script-compiler.d.ts +4 -1
- package/dist/types/compiler/style-compiler.d.ts +2 -1
- package/dist/types/compiler/template-compiler.d.ts +1 -0
- package/dist/types/compiler.d.ts +2 -1
- package/dist/types/core/quantum.d.ts +28 -0
- package/dist/types/core/query.d.ts +6 -6
- package/dist/types/core/surge.d.ts +21 -0
- package/dist/types/core/vault.d.ts +0 -1
- package/dist/types/index.d.ts +16 -6
- package/dist/types/script-compiler.d.ts +4 -1
- package/dist/types/style-compiler.d.ts +2 -1
- package/dist/types/template-compiler.d.ts +1 -0
- package/package.json +1 -1
- package/src/compiler/compiler.ts +90 -5
- package/src/compiler/script-compiler.ts +189 -21
- package/src/compiler/style-compiler.ts +28 -4
- package/src/compiler/template-compiler.ts +52 -4
- package/src/loader/index.js +16 -41
package/dist/core/quantum.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { muState } from './hooks';
|
|
2
|
+
/**
|
|
3
|
+
* Mulan Quantum (ASTR-Q+) Core
|
|
4
|
+
* Advanced Simulation Engine for multi-qubit registers and entanglement.
|
|
5
|
+
*/
|
|
6
|
+
// -- GLOBAL CONTEXT FOR QUANTUM CONTROL --
|
|
7
|
+
// Defined at top to ensure visibility for muGate
|
|
8
|
+
export let activeControls = [];
|
|
2
9
|
/**
|
|
3
10
|
* Creates a quantum register of size n.
|
|
4
11
|
* State vector will have 2^n amplitudes.
|
|
@@ -54,14 +61,14 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
54
61
|
const n = state.size;
|
|
55
62
|
const amplitudes = state.amplitudes;
|
|
56
63
|
const newAmps = amplitudes.map(a => (Object.assign({}, a)));
|
|
64
|
+
// Prepare Effective Control (Explicit Arguments + Global Context)
|
|
65
|
+
const effectiveControl = [...(control === undefined ? [] : (Array.isArray(control) ? control : [control])), ...activeControls];
|
|
57
66
|
// Helper: Check if all control bits are 1
|
|
58
67
|
const checkControl = (index, ctrl) => {
|
|
59
|
-
if (ctrl === undefined)
|
|
68
|
+
if (ctrl === undefined || (Array.isArray(ctrl) && ctrl.length === 0))
|
|
60
69
|
return true;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
return ctrl.every(c => ((index >> c) & 1) === 1);
|
|
70
|
+
const ctrls = Array.isArray(ctrl) ? ctrl : [ctrl];
|
|
71
|
+
return ctrls.every(c => ((index >> c) & 1) === 1);
|
|
65
72
|
};
|
|
66
73
|
// SWAP Gate (Unique case: affects 2 targets)
|
|
67
74
|
if (type === 'SWAP') {
|
|
@@ -69,6 +76,9 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
69
76
|
const t2 = control; // SWAP uses control arg as second target
|
|
70
77
|
// Iterate only half to avoid double swapping
|
|
71
78
|
for (let i = 0; i < amplitudes.length; i++) {
|
|
79
|
+
// Check active controls for SWAP too
|
|
80
|
+
if (activeControls.length > 0 && !checkControl(i, activeControls))
|
|
81
|
+
continue;
|
|
72
82
|
const bit1 = (i >> t1) & 1;
|
|
73
83
|
const bit2 = (i >> t2) & 1;
|
|
74
84
|
if (bit1 !== bit2) {
|
|
@@ -93,7 +103,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
93
103
|
if (processed.has(i))
|
|
94
104
|
continue;
|
|
95
105
|
// Check Controls first
|
|
96
|
-
if (!checkControl(i,
|
|
106
|
+
if (!checkControl(i, effectiveControl))
|
|
97
107
|
continue;
|
|
98
108
|
const targetBit = (i >> target) & 1;
|
|
99
109
|
const pairedIndex = targetBit ? (i & ~(1 << target)) : (i | (1 << target));
|
|
@@ -114,7 +124,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
114
124
|
else if (type === 'X' || type === 'CNOT') {
|
|
115
125
|
// CNOT is just Controlled-X
|
|
116
126
|
for (let i = 0; i < amplitudes.length; i++) {
|
|
117
|
-
if (!checkControl(i,
|
|
127
|
+
if (!checkControl(i, effectiveControl))
|
|
118
128
|
continue;
|
|
119
129
|
const targetBit = (i >> target) & 1;
|
|
120
130
|
const pairedIndex = targetBit ? (i & ~(1 << target)) : (i | (1 << target));
|
|
@@ -128,7 +138,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
128
138
|
else if (type === 'Z' || type === 'CZ') {
|
|
129
139
|
// Z and CZ are Phase Flips
|
|
130
140
|
for (let i = 0; i < amplitudes.length; i++) {
|
|
131
|
-
if (!checkControl(i,
|
|
141
|
+
if (!checkControl(i, effectiveControl))
|
|
132
142
|
continue;
|
|
133
143
|
const targetBit = (i >> target) & 1;
|
|
134
144
|
// Z Gate acts on |1>
|
|
@@ -140,7 +150,7 @@ export function muGate(reg, type, target = 0, control) {
|
|
|
140
150
|
else if (type === 'Y') {
|
|
141
151
|
// Y: |0> -> i|1>, |1> -> -i|0>
|
|
142
152
|
for (let i = 0; i < amplitudes.length; i++) {
|
|
143
|
-
if (!checkControl(i,
|
|
153
|
+
if (!checkControl(i, effectiveControl))
|
|
144
154
|
continue;
|
|
145
155
|
const targetBit = (i >> target) & 1;
|
|
146
156
|
const pairedIndex = targetBit ? (i & ~(1 << target)) : (i | (1 << target));
|
|
@@ -282,3 +292,58 @@ export function muMeasure(reg, target = 0) {
|
|
|
282
292
|
updateState(reg, Object.assign(Object.assign({}, state), { amplitudes: newAmps }));
|
|
283
293
|
return result;
|
|
284
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Quantum Loop: Parallel Execution
|
|
297
|
+
* Applies a gate to multiple qubits "simultaneously" (in simulation steps).
|
|
298
|
+
* Ideal for initialization (Hadamard Transform) or global operations.
|
|
299
|
+
* @param reg Quantum Register
|
|
300
|
+
* @param qubits Array of qubit indices
|
|
301
|
+
* @param gate Gate type to apply (e.g. 'H', 'X')
|
|
302
|
+
*/
|
|
303
|
+
export function muParallel(reg, qubits, gate) {
|
|
304
|
+
if (gate === 'SWAP') {
|
|
305
|
+
throw new Error("SWAP cannot be applied in parallel (requires pairs).");
|
|
306
|
+
}
|
|
307
|
+
// In a real quantum computer, these happen at t=0.
|
|
308
|
+
// Here, we loop, but logical time is constant.
|
|
309
|
+
qubits.forEach(q => muGate(reg, gate, q));
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Applies a block of operations controlled by specific qubits.
|
|
313
|
+
* Enables "Quantum If/Else".
|
|
314
|
+
*/
|
|
315
|
+
export function muControl(reg, controlQubit, inverse, block) {
|
|
316
|
+
// 1. Setup Context
|
|
317
|
+
if (inverse) {
|
|
318
|
+
muGate(reg, 'X', controlQubit); // Flip 0 to 1 to activate
|
|
319
|
+
}
|
|
320
|
+
activeControls.push(controlQubit);
|
|
321
|
+
try {
|
|
322
|
+
block();
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
activeControls.pop();
|
|
326
|
+
// Uncompute (Restore 0)
|
|
327
|
+
if (inverse) {
|
|
328
|
+
muGate(reg, 'X', controlQubit);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Quantum Switch: conditional Logic on Superposition
|
|
334
|
+
* Executes different logic branches based on the state of control qubits.
|
|
335
|
+
* Because the register can be in a superposition of states (e.g. |0> + |1>),
|
|
336
|
+
* MULTIPLE branches can execute effectively simultaneously on different subspaces.
|
|
337
|
+
*
|
|
338
|
+
* @param reg Quantum Register
|
|
339
|
+
* @param controlQubit The qubit controlling the switch (Single control for v1)
|
|
340
|
+
* @param cases Object mapping state (0 or 1) to a function executing quantum operations
|
|
341
|
+
*/
|
|
342
|
+
export function muSwitch(reg, controlQubit, cases) {
|
|
343
|
+
if (cases[0]) {
|
|
344
|
+
muControl(reg, controlQubit, true, cases[0]);
|
|
345
|
+
}
|
|
346
|
+
if (cases[1]) {
|
|
347
|
+
muControl(reg, controlQubit, false, cases[1]);
|
|
348
|
+
}
|
|
349
|
+
}
|
package/dist/core/query.js
CHANGED
|
@@ -35,7 +35,12 @@ export function useQuery(queryFn, options = { enabled: true }) {
|
|
|
35
35
|
execute();
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
-
return
|
|
38
|
+
return {
|
|
39
|
+
get data() { return state.data; },
|
|
40
|
+
get isLoading() { return state.isLoading; },
|
|
41
|
+
get error() { return state.error; },
|
|
42
|
+
refetch: execute
|
|
43
|
+
};
|
|
39
44
|
}
|
|
40
45
|
export function useMutation(mutationFn) {
|
|
41
46
|
const state = reactive({
|
|
@@ -59,5 +64,10 @@ export function useMutation(mutationFn) {
|
|
|
59
64
|
state.isLoading = false;
|
|
60
65
|
}
|
|
61
66
|
});
|
|
62
|
-
return
|
|
67
|
+
return {
|
|
68
|
+
get data() { return state.data; },
|
|
69
|
+
get isLoading() { return state.isLoading; },
|
|
70
|
+
get error() { return state.error; },
|
|
71
|
+
mutate
|
|
72
|
+
};
|
|
63
73
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* muBurst - Adaptive Non-blocking Iterator
|
|
3
|
+
* Processes large arrays in batches within a frame budget (typically 8-16ms)
|
|
4
|
+
* to keep the UI responsive while executing at near-native loop speeds.
|
|
5
|
+
*/
|
|
6
|
+
export function muBurst(array, callback, options = {}) {
|
|
7
|
+
const { chunkSize = 1000, timeout = 8, onProgress } = options;
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
let index = 0;
|
|
10
|
+
const total = array.length;
|
|
11
|
+
function process() {
|
|
12
|
+
const start = performance.now();
|
|
13
|
+
// Tight loop for high-speed processing
|
|
14
|
+
while (index < total && (performance.now() - start) < timeout) {
|
|
15
|
+
// Process in smaller bursts to allow more frequent time checks if needed
|
|
16
|
+
const endBurst = Math.min(index + chunkSize, total);
|
|
17
|
+
for (; index < endBurst; index++) {
|
|
18
|
+
callback(array[index], index);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (onProgress) {
|
|
22
|
+
onProgress((index / total) * 100);
|
|
23
|
+
}
|
|
24
|
+
if (index < total) {
|
|
25
|
+
requestAnimationFrame(process);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
resolve();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
process();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* muSurge - Truly Parallel Execution
|
|
36
|
+
* Distributes work across CPU cores using Web Workers.
|
|
37
|
+
* Logic must be serializable.
|
|
38
|
+
*/
|
|
39
|
+
export function muSurge(array, taskFn, onProgress) {
|
|
40
|
+
const n = navigator.hardwareConcurrency || 4;
|
|
41
|
+
const chunkSize = Math.ceil(array.length / n);
|
|
42
|
+
const results = new Array(array.length);
|
|
43
|
+
let completedChunks = 0;
|
|
44
|
+
let completedItems = 0;
|
|
45
|
+
// Convert function to string if it isn't already
|
|
46
|
+
const fnStr = typeof taskFn === 'function' ? taskFn.toString() : taskFn;
|
|
47
|
+
const workerCode = `
|
|
48
|
+
const taskFn = ${fnStr};
|
|
49
|
+
self.onmessage = function(e) {
|
|
50
|
+
const { chunk, startIndex } = e.data;
|
|
51
|
+
try {
|
|
52
|
+
const results = chunk.map(taskFn);
|
|
53
|
+
self.postMessage({ results, startIndex });
|
|
54
|
+
} catch (err) {
|
|
55
|
+
self.postMessage({ error: err.message, startIndex });
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
`;
|
|
59
|
+
const blob = new Blob([workerCode], { type: 'application/javascript' });
|
|
60
|
+
const workerUrl = URL.createObjectURL(blob);
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
if (array.length === 0)
|
|
63
|
+
return resolve([]);
|
|
64
|
+
for (let i = 0; i < n; i++) {
|
|
65
|
+
const start = i * chunkSize;
|
|
66
|
+
const end = Math.min(start + chunkSize, array.length);
|
|
67
|
+
if (start >= end) {
|
|
68
|
+
completedChunks++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const chunk = array.slice(start, end);
|
|
72
|
+
const worker = new Worker(workerUrl);
|
|
73
|
+
worker.onmessage = (e) => {
|
|
74
|
+
const { results: chunkResults, startIndex } = e.data;
|
|
75
|
+
// Merge results back into main array
|
|
76
|
+
for (let j = 0; j < chunkResults.length; j++) {
|
|
77
|
+
results[startIndex + j] = chunkResults[j];
|
|
78
|
+
}
|
|
79
|
+
completedChunks++;
|
|
80
|
+
completedItems += chunkResults.length;
|
|
81
|
+
if (onProgress)
|
|
82
|
+
onProgress((completedItems / array.length) * 100);
|
|
83
|
+
worker.terminate();
|
|
84
|
+
if (completedChunks === n) {
|
|
85
|
+
URL.revokeObjectURL(workerUrl);
|
|
86
|
+
resolve(results);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
worker.postMessage({ chunk, startIndex: start, fnStr });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
package/dist/core/vault.js
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
1
|
import { muEffect } from './hooks';
|
|
2
2
|
import { reactive } from './reactive';
|
|
3
|
-
const MULAN_SECRET = 'b3ast_mulan_s3cur1ty_k3y';
|
|
4
|
-
function beastXOR(str) {
|
|
5
|
-
let result = '';
|
|
6
|
-
for (let i = 0; i < str.length; i++) {
|
|
7
|
-
result += String.fromCharCode(str.charCodeAt(i) ^ MULAN_SECRET.charCodeAt(i % MULAN_SECRET.length));
|
|
8
|
-
}
|
|
9
|
-
return btoa(result);
|
|
10
|
-
}
|
|
11
|
-
function beastDecode(encoded) {
|
|
12
|
-
const str = atob(encoded);
|
|
13
|
-
let result = '';
|
|
14
|
-
for (let i = 0; i < str.length; i++) {
|
|
15
|
-
result += String.fromCharCode(str.charCodeAt(i) ^ MULAN_SECRET.charCodeAt(i % MULAN_SECRET.length));
|
|
16
|
-
}
|
|
17
|
-
return result;
|
|
18
|
-
}
|
|
19
3
|
/**
|
|
20
4
|
* Mulan Vault: The World's First Native Persistent State Primitive.
|
|
21
|
-
* Now fortified with Iron Fortress Obfuscation.
|
|
22
5
|
*/
|
|
23
6
|
export function persistent(key, initialValue, options = {}) {
|
|
24
7
|
const storage = options.storage || window.localStorage;
|
|
@@ -27,11 +10,10 @@ export function persistent(key, initialValue, options = {}) {
|
|
|
27
10
|
let startVal = initialValue;
|
|
28
11
|
if (stored) {
|
|
29
12
|
try {
|
|
30
|
-
|
|
31
|
-
startVal = JSON.parse(raw);
|
|
13
|
+
startVal = JSON.parse(stored);
|
|
32
14
|
}
|
|
33
15
|
catch (e) {
|
|
34
|
-
console.warn(`[
|
|
16
|
+
console.warn(`[Mulan Vault] Corrupt persistent data for key "${key}", resetting.`);
|
|
35
17
|
}
|
|
36
18
|
}
|
|
37
19
|
// 2. Create Reactive State (Follow muState pattern for consistency)
|
|
@@ -41,20 +23,19 @@ export function persistent(key, initialValue, options = {}) {
|
|
|
41
23
|
muEffect(() => {
|
|
42
24
|
try {
|
|
43
25
|
const payload = isObject ? state : state.value;
|
|
44
|
-
const
|
|
45
|
-
|
|
26
|
+
const toSave = JSON.stringify(payload);
|
|
27
|
+
// Non-obfuscated persistence to satisfy security audits
|
|
46
28
|
storage.setItem(key, toSave);
|
|
47
29
|
}
|
|
48
30
|
catch (e) {
|
|
49
|
-
console.error(`[
|
|
31
|
+
console.error(`[Mulan Vault] Failed to save key "${key}"`);
|
|
50
32
|
}
|
|
51
33
|
});
|
|
52
34
|
// 4. Sync across Tabs
|
|
53
35
|
const sync = (e) => {
|
|
54
36
|
if (e.key === key && e.newValue) {
|
|
55
37
|
try {
|
|
56
|
-
const
|
|
57
|
-
const newVal = JSON.parse(raw);
|
|
38
|
+
const newVal = JSON.parse(e.newValue);
|
|
58
39
|
if (isObject) {
|
|
59
40
|
Object.assign(state, newVal);
|
|
60
41
|
}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from './core/hooks';
|
|
|
8
8
|
export * from './core/query';
|
|
9
9
|
export * from './core/vault';
|
|
10
10
|
export * from './core/quantum';
|
|
11
|
+
export * from './core/surge';
|
|
11
12
|
export * from './components/bloch-sphere';
|
|
12
13
|
export * from './components/infinity-list';
|
|
13
14
|
// Global Mulan Object for non-module usage
|
|
@@ -20,9 +21,10 @@ import * as Hooks from './core/hooks';
|
|
|
20
21
|
import * as Query from './core/query';
|
|
21
22
|
import { render } from './core/renderer';
|
|
22
23
|
import * as Quantum from './core/quantum';
|
|
24
|
+
import * as Surge from './core/surge';
|
|
23
25
|
import * as InfinityList from './components/infinity-list';
|
|
24
|
-
const Mulan = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ reactive,
|
|
25
|
-
effect, Component: MuComponent, defineComponent, Router: MuRouter, createRouter, Store: MuStore, Security: Security }, Hooks), Query), Quantum), InfinityList), { render,
|
|
26
|
+
const Mulan = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ reactive,
|
|
27
|
+
effect, Component: MuComponent, defineComponent, Router: MuRouter, createRouter, Store: MuStore, Security: Security }, Hooks), Query), Quantum), Surge), InfinityList), { render,
|
|
26
28
|
// MULAN INSIGHT: Branded Logging
|
|
27
29
|
log: (msg, ...args) => {
|
|
28
30
|
console.log(`%c[MulanJS]%c ${msg}`, "color: #ff3e00; font-weight: bold; background: #222; padding: 2px 4px; border-radius: 3px;", "", ...args);
|