react-state-basis 0.4.1 → 0.5.0
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 +62 -308
- package/dist/index.d.mts +30 -16
- package/dist/index.d.ts +30 -16
- package/dist/index.js +507 -376
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +508 -381
- package/dist/index.mjs.map +1 -1
- package/dist/plugin.js +48 -22
- package/dist/production.d.mts +14 -6
- package/dist/production.d.ts +14 -6
- package/dist/production.js +21 -6
- package/dist/production.js.map +1 -1
- package/dist/production.mjs +19 -6
- package/dist/production.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,11 +33,14 @@ __export(index_exports, {
|
|
|
33
33
|
BasisProvider: () => BasisProvider,
|
|
34
34
|
basis: () => basis,
|
|
35
35
|
configureBasis: () => configureBasis,
|
|
36
|
+
createContext: () => createContext,
|
|
37
|
+
getBasisMetrics: () => getBasisMetrics,
|
|
36
38
|
printBasisHealthReport: () => printBasisHealthReport,
|
|
37
39
|
use: () => use,
|
|
38
|
-
useActionState: () =>
|
|
40
|
+
useActionState: () => useActionState,
|
|
39
41
|
useBasisConfig: () => useBasisConfig,
|
|
40
42
|
useCallback: () => useCallback,
|
|
43
|
+
useContext: () => useContext,
|
|
41
44
|
useDebugValue: () => useDebugValue2,
|
|
42
45
|
useDeferredValue: () => useDeferredValue,
|
|
43
46
|
useEffect: () => useEffect,
|
|
@@ -46,7 +49,7 @@ __export(index_exports, {
|
|
|
46
49
|
useInsertionEffect: () => useInsertionEffect2,
|
|
47
50
|
useLayoutEffect: () => useLayoutEffect,
|
|
48
51
|
useMemo: () => useMemo,
|
|
49
|
-
useOptimistic: () =>
|
|
52
|
+
useOptimistic: () => useOptimistic,
|
|
50
53
|
useReducer: () => useReducer,
|
|
51
54
|
useRef: () => useRef,
|
|
52
55
|
useState: () => useState,
|
|
@@ -59,10 +62,39 @@ module.exports = __toCommonJS(index_exports);
|
|
|
59
62
|
var React = __toESM(require("react"));
|
|
60
63
|
var import_react = require("react");
|
|
61
64
|
|
|
65
|
+
// src/core/math.ts
|
|
66
|
+
var calculateSimilarityCircular = (bufferA, headA, bufferB, headB, offset) => {
|
|
67
|
+
const L = bufferA.length;
|
|
68
|
+
let dot = 0, magA = 0, magB = 0;
|
|
69
|
+
const baseOffset = ((headB - headA + offset) % L + L) % L;
|
|
70
|
+
for (let i = 0; i < L; i++) {
|
|
71
|
+
const valA = bufferA[i];
|
|
72
|
+
let iB = i + baseOffset;
|
|
73
|
+
if (iB >= L) {
|
|
74
|
+
iB -= L;
|
|
75
|
+
}
|
|
76
|
+
const valB = bufferB[iB];
|
|
77
|
+
dot += valA * valB;
|
|
78
|
+
magA += valA * valA;
|
|
79
|
+
magB += valB * valB;
|
|
80
|
+
}
|
|
81
|
+
if (magA === 0 || magB === 0) return 0;
|
|
82
|
+
return dot / (Math.sqrt(magA) * Math.sqrt(magB));
|
|
83
|
+
};
|
|
84
|
+
var calculateCosineSimilarity = (A, B) => {
|
|
85
|
+
let dot = 0, magA = 0, magB = 0;
|
|
86
|
+
for (let i = 0; i < A.length; i++) {
|
|
87
|
+
dot += A[i] * B[i];
|
|
88
|
+
magA += A[i] * A[i];
|
|
89
|
+
magB += B[i] * B[i];
|
|
90
|
+
}
|
|
91
|
+
return magA === 0 || magB === 0 ? 0 : dot / (Math.sqrt(magA) * Math.sqrt(magB));
|
|
92
|
+
};
|
|
93
|
+
|
|
62
94
|
// src/core/logger.ts
|
|
63
95
|
var isWeb = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
64
96
|
var LAST_LOG_TIMES = /* @__PURE__ */ new Map();
|
|
65
|
-
var LOG_COOLDOWN =
|
|
97
|
+
var LOG_COOLDOWN = 3e3;
|
|
66
98
|
var STYLES = {
|
|
67
99
|
basis: "background: #6c5ce7; color: white; font-weight: bold; padding: 2px 6px; border-radius: 3px;",
|
|
68
100
|
version: "background: #a29bfe; color: #2d3436; padding: 2px 6px; border-radius: 3px; margin-left: -4px;",
|
|
@@ -71,9 +103,10 @@ var STYLES = {
|
|
|
71
103
|
headerGreen: "background: #00b894; color: white; font-weight: bold; padding: 4px 8px; border-radius: 4px;",
|
|
72
104
|
label: "background: #dfe6e9; color: #2d3436; padding: 0 4px; border-radius: 3px; font-family: monospace; font-weight: bold; border: 1px solid #b2bec3;",
|
|
73
105
|
location: "color: #0984e3; font-family: monospace; font-weight: bold;",
|
|
74
|
-
codeBlock: "background: #1e1e1e; color: #9cdcfe; padding: 8px 12px; display: block; margin: 4px 0; border-left: 3px solid #00b894; font-family: monospace; line-height: 1.4; border-radius: 0 3px 3px 0;",
|
|
75
106
|
subText: "color: #636e72; font-size: 11px;",
|
|
76
|
-
bold: "font-weight: bold;"
|
|
107
|
+
bold: "font-weight: bold;",
|
|
108
|
+
action: "color: #00b894; font-weight: bold; border: 1px solid #00b894; padding: 0 4px; border-radius: 3px;",
|
|
109
|
+
warning: "color: #d63031; font-weight: bold; border: 1px solid #d63031; padding: 0 4px; border-radius: 3px;"
|
|
77
110
|
};
|
|
78
111
|
var parseLabel = (label) => {
|
|
79
112
|
const parts = label.split(" -> ");
|
|
@@ -84,384 +117,482 @@ var shouldLog = (key) => {
|
|
|
84
117
|
const last = LAST_LOG_TIMES.get(key) || 0;
|
|
85
118
|
if (now - last > LOG_COOLDOWN) {
|
|
86
119
|
LAST_LOG_TIMES.set(key, now);
|
|
87
|
-
if (LAST_LOG_TIMES.size > 100) {
|
|
88
|
-
const cutoff = now - 36e5;
|
|
89
|
-
for (const [k, v] of LAST_LOG_TIMES.entries()) {
|
|
90
|
-
if (v < cutoff) LAST_LOG_TIMES.delete(k);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
120
|
return true;
|
|
94
121
|
}
|
|
95
122
|
return false;
|
|
96
123
|
};
|
|
97
|
-
var
|
|
98
|
-
if (!isWeb) return;
|
|
99
|
-
console.log(
|
|
100
|
-
`%cBasis%cAuditor%c | Temporal Analysis Active (Window: ${windowSize})`,
|
|
101
|
-
STYLES.basis,
|
|
102
|
-
STYLES.version,
|
|
103
|
-
"color: #636e72; font-style: italic; margin-left: 8px;"
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
var displayRedundancyAlert = (labelA, labelB, sim) => {
|
|
124
|
+
var displayRedundancyAlert = (labelA, metaA, labelB, metaB, sim) => {
|
|
107
125
|
if (!isWeb || !shouldLog(`redundant-${labelA}-${labelB}`)) return;
|
|
108
126
|
const infoA = parseLabel(labelA);
|
|
109
127
|
const infoB = parseLabel(labelB);
|
|
110
|
-
|
|
128
|
+
const isContextMirror = metaA.role === "local" && metaB.role === "context" || metaB.role === "local" && metaA.role === "context";
|
|
129
|
+
const local = metaA.role === "local" ? infoA : infoB;
|
|
130
|
+
const context = metaA.role === "context" ? infoA : infoB;
|
|
131
|
+
console.group(`%c \u264A BASIS | ${isContextMirror ? "CONTEXT MIRRORING" : "DUPLICATE STATE"} `, STYLES.headerRed);
|
|
111
132
|
console.log(`%c\u{1F4CD} Location: %c${infoA.file}`, STYLES.bold, STYLES.location);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
%
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
`%
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
"",
|
|
148
|
-
STYLES.label,
|
|
149
|
-
""
|
|
150
|
-
);
|
|
151
|
-
console.log(
|
|
152
|
-
`%cContext:%c ${method === "math" ? "The engine detected a consistent 20ms lag between these updates." : "This was caught during React effect execution."}
|
|
153
|
-
%cResult:%c This creates a %cDouble Render Cycle%c.`,
|
|
154
|
-
STYLES.bold,
|
|
155
|
-
"",
|
|
156
|
-
STYLES.bold,
|
|
157
|
-
"",
|
|
158
|
-
"color: #d63031; font-weight: bold;",
|
|
159
|
-
""
|
|
160
|
-
);
|
|
133
|
+
if (isContextMirror) {
|
|
134
|
+
console.log(
|
|
135
|
+
`%cIssue:%c Local variable %c${local.name}%c is just a copy of Global Context %c${context.name}%c.
|
|
136
|
+
%cConfidence: ${(sim * 100).toFixed(0)}%`,
|
|
137
|
+
STYLES.bold,
|
|
138
|
+
"",
|
|
139
|
+
STYLES.label,
|
|
140
|
+
"",
|
|
141
|
+
STYLES.label,
|
|
142
|
+
"",
|
|
143
|
+
STYLES.subText
|
|
144
|
+
);
|
|
145
|
+
console.log(`%cFix:%c Use the context value directly to avoid state drift.`, STYLES.bold, STYLES.warning);
|
|
146
|
+
} else {
|
|
147
|
+
console.log(
|
|
148
|
+
`%cIssue:%c %c${infoA.name}%c and %c${infoB.name}%c are synchronized (${(sim * 100).toFixed(0)}% correlation).`,
|
|
149
|
+
STYLES.bold,
|
|
150
|
+
"",
|
|
151
|
+
STYLES.label,
|
|
152
|
+
"",
|
|
153
|
+
STYLES.label,
|
|
154
|
+
""
|
|
155
|
+
);
|
|
156
|
+
console.log(
|
|
157
|
+
`%cFix:%c Merge states or calculate %c${infoB.name}%c from %c${infoA.name}%c via %cuseMemo%c.`,
|
|
158
|
+
STYLES.bold,
|
|
159
|
+
"",
|
|
160
|
+
STYLES.label,
|
|
161
|
+
"",
|
|
162
|
+
STYLES.label,
|
|
163
|
+
"",
|
|
164
|
+
STYLES.action,
|
|
165
|
+
""
|
|
166
|
+
);
|
|
167
|
+
}
|
|
161
168
|
console.groupEnd();
|
|
162
169
|
};
|
|
163
|
-
var
|
|
170
|
+
var displayHealthReport = (history2, threshold) => {
|
|
164
171
|
if (!isWeb) return;
|
|
165
|
-
const info = parseLabel(label);
|
|
166
|
-
console.group(`%c \u{1F6D1} BASIS CRITICAL | CIRCUIT BREAKER `, STYLES.headerRed);
|
|
167
|
-
console.error(`Infinite oscillation on: %c${info.name}%c`, "color: white; background: #d63031; padding: 2px 4px;", "");
|
|
168
|
-
console.groupEnd();
|
|
169
|
-
};
|
|
170
|
-
var displayHealthReport = (history2, similarityFn, threshold) => {
|
|
171
172
|
const entries = Array.from(history2.entries());
|
|
172
173
|
const totalVars = entries.length;
|
|
173
174
|
if (totalVars === 0) return;
|
|
174
175
|
const clusters = [];
|
|
175
176
|
const processed = /* @__PURE__ */ new Set();
|
|
176
177
|
let independentCount = 0;
|
|
177
|
-
entries.forEach(([labelA,
|
|
178
|
+
entries.forEach(([labelA, metaA]) => {
|
|
178
179
|
if (processed.has(labelA)) return;
|
|
179
180
|
const currentCluster = [labelA];
|
|
180
181
|
processed.add(labelA);
|
|
181
|
-
entries.forEach(([labelB,
|
|
182
|
+
entries.forEach(([labelB, metaB]) => {
|
|
182
183
|
if (labelA === labelB || processed.has(labelB)) return;
|
|
183
|
-
const sim =
|
|
184
|
+
const sim = calculateCosineSimilarity(metaA.buffer, metaB.buffer);
|
|
184
185
|
if (sim > threshold) {
|
|
186
|
+
if (metaA.role === "context" && metaB.role === "context") return;
|
|
185
187
|
currentCluster.push(labelB);
|
|
186
188
|
processed.add(labelB);
|
|
187
189
|
}
|
|
188
190
|
});
|
|
189
|
-
if (currentCluster.length > 1)
|
|
190
|
-
|
|
191
|
-
} else {
|
|
192
|
-
independentCount++;
|
|
193
|
-
}
|
|
191
|
+
if (currentCluster.length > 1) clusters.push(currentCluster);
|
|
192
|
+
else independentCount++;
|
|
194
193
|
});
|
|
195
194
|
const systemRank = independentCount + clusters.length;
|
|
196
195
|
const healthScore = systemRank / totalVars * 100;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
});
|
|
211
|
-
console.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
});
|
|
227
|
-
console.table(matrix);
|
|
196
|
+
console.group(`%c \u{1F4CA} BASIS | ARCHITECTURAL HEALTH REPORT `, STYLES.headerGreen);
|
|
197
|
+
console.log(
|
|
198
|
+
`%cEfficiency: %c${healthScore.toFixed(1)}% %c(${systemRank}/${totalVars} Sources of Truth)`,
|
|
199
|
+
STYLES.bold,
|
|
200
|
+
`color: ${healthScore > 85 ? "#00b894" : "#d63031"}; font-weight: bold;`,
|
|
201
|
+
STYLES.subText
|
|
202
|
+
);
|
|
203
|
+
if (clusters.length > 0) {
|
|
204
|
+
console.log(`%cDetected ${clusters.length} Sync Issues:`, "font-weight: bold; color: #e17055; margin-top: 10px;");
|
|
205
|
+
clusters.forEach((cluster, idx) => {
|
|
206
|
+
const clusterMetas = cluster.map((l) => ({ label: l, meta: history2.get(l), info: parseLabel(l) }));
|
|
207
|
+
const contexts = clusterMetas.filter((c) => c.meta.role === "context");
|
|
208
|
+
const locals = clusterMetas.filter((c) => c.meta.role === "local");
|
|
209
|
+
const names = clusterMetas.map((c) => `${c.meta.role === "context" ? "\u03A9 " : ""}${c.info.name}`).join(" \u27F7 ");
|
|
210
|
+
console.group(` %c${idx + 1}%c ${names}`, "background: #e17055; color: white; border-radius: 50%; padding: 0 5px;", "font-family: monospace; font-weight: bold;");
|
|
211
|
+
if (contexts.length > 0) {
|
|
212
|
+
const ctxNames = contexts.map((c) => c.info.name).join(", ");
|
|
213
|
+
console.log(`%cDiagnosis:%c Context Mirroring. Variables are copying from %c${ctxNames}%c.`, STYLES.bold, "", STYLES.label, "");
|
|
214
|
+
console.log(`%cSolution:%c Use the context directly to avoid state drift.`, STYLES.bold, STYLES.action);
|
|
215
|
+
} else {
|
|
216
|
+
const isExplosion = locals.length > 2;
|
|
217
|
+
if (isExplosion) {
|
|
218
|
+
console.log(`%cDiagnosis:%c Boolean Explosion. Multiple states updating in sync.`, STYLES.bold, "");
|
|
219
|
+
console.log(`%cSolution:%c Combine into a single %cstatus%c string or a %creducer%c.`, STYLES.bold, "", STYLES.label, "", STYLES.label, "");
|
|
220
|
+
} else {
|
|
221
|
+
console.log(`%cDiagnosis:%c Redundant State. Variables always change together.`, STYLES.bold, "");
|
|
222
|
+
console.log(`%cSolution:%c Derive one from the other via %cuseMemo%c.`, STYLES.bold, "", STYLES.label, "");
|
|
223
|
+
}
|
|
224
|
+
}
|
|
228
225
|
console.groupEnd();
|
|
229
|
-
}
|
|
230
|
-
console.groupEnd();
|
|
226
|
+
});
|
|
231
227
|
} else {
|
|
232
|
-
console.log(
|
|
228
|
+
console.log("%c\u2728 Your architecture is clean. No redundant state detected.", "color: #00b894; font-weight: bold;");
|
|
233
229
|
}
|
|
230
|
+
console.groupEnd();
|
|
234
231
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
232
|
+
var displayCausalHint = (targetLabel, targetMeta, sourceLabel, sourceMeta) => {
|
|
233
|
+
if (!isWeb || !shouldLog(`causal-${sourceLabel}-${targetLabel}`)) return;
|
|
234
|
+
const target = parseLabel(targetLabel);
|
|
235
|
+
const source = parseLabel(sourceLabel);
|
|
236
|
+
const isContextTrigger = sourceMeta.role === "context";
|
|
237
|
+
console.groupCollapsed(`%c \u26A1 BASIS | ${isContextTrigger ? "CONTEXT SYNC LEAK" : "DOUBLE RENDER"} `, STYLES.headerBlue);
|
|
238
|
+
console.log(`%c\u{1F4CD} Location: %c${target.file}`, STYLES.bold, STYLES.location);
|
|
239
|
+
if (isContextTrigger) {
|
|
240
|
+
console.log(`%cIssue:%c Context %c${source.name}%c updated, then local %c${target.name}%c followed 1 frame later.`, STYLES.bold, "", STYLES.label, "", STYLES.label, "");
|
|
241
|
+
console.log(`%cImpact: This forces React to render the component twice for every change.`, STYLES.subText);
|
|
242
|
+
} else {
|
|
243
|
+
console.log(`%cIssue:%c %c${source.name}%c triggers %c${target.name}%c in a separate frame.`, STYLES.bold, "", STYLES.label, "", STYLES.label, "");
|
|
247
244
|
}
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
console.log(`%cFix:%c Derive %c${target.name}%c during the first render.`, STYLES.bold, STYLES.action, STYLES.label, "");
|
|
246
|
+
console.groupEnd();
|
|
250
247
|
};
|
|
251
|
-
var
|
|
252
|
-
|
|
248
|
+
var displayViolentBreaker = (label, count, threshold) => {
|
|
249
|
+
if (!isWeb) return;
|
|
250
|
+
const parts = label.split(" -> ");
|
|
251
|
+
console.group(`%c \u{1F6D1} BASIS CRITICAL | CIRCUIT BREAKER `, "background: #dc2626; color: white; font-weight: bold; padding: 8px 16px;");
|
|
252
|
+
console.error(`INFINITE LOOP DETECTED
|
|
253
|
+
Variable: ${parts[1] || label}
|
|
254
|
+
Frequency: ${count} updates/sec`);
|
|
255
|
+
console.log(`%cACTION: Update BLOCKED to prevent browser freeze.`, "color: #dc2626; font-weight: bold;");
|
|
256
|
+
console.groupEnd();
|
|
257
|
+
};
|
|
258
|
+
var displayBootLog = (windowSize) => {
|
|
259
|
+
if (!isWeb) return;
|
|
260
|
+
console.log(`%cBasis%cAuditor%c | v0.5.x Architectural Forensics Active (Window: ${windowSize})`, STYLES.basis, STYLES.version, "color: #636e72; font-style: italic; margin-left: 8px;");
|
|
253
261
|
};
|
|
254
262
|
|
|
255
263
|
// src/core/constants.ts
|
|
256
264
|
var WINDOW_SIZE = 50;
|
|
257
265
|
var SIMILARITY_THRESHOLD = 0.88;
|
|
258
266
|
var LOOP_THRESHOLD = 150;
|
|
259
|
-
var LOOP_WINDOW_MS = 1e3;
|
|
260
|
-
var ANALYSIS_INTERVAL = 5;
|
|
261
267
|
var VOLATILITY_THRESHOLD = 25;
|
|
262
268
|
|
|
269
|
+
// src/core/analysis.ts
|
|
270
|
+
var calculateAllSimilarities = (entryA, entryB) => {
|
|
271
|
+
const sync = calculateSimilarityCircular(entryA.meta.buffer, entryA.meta.head, entryB.meta.buffer, entryB.meta.head, 0);
|
|
272
|
+
const bA = calculateSimilarityCircular(entryA.meta.buffer, entryA.meta.head, entryB.meta.buffer, entryB.meta.head, 1);
|
|
273
|
+
const aB = calculateSimilarityCircular(entryA.meta.buffer, entryA.meta.head, entryB.meta.buffer, entryB.meta.head, -1);
|
|
274
|
+
return { sync, bA, aB, max: Math.max(sync, bA, aB) };
|
|
275
|
+
};
|
|
276
|
+
var shouldSkipComparison = (entryA, entryB, dirtyLabels2) => {
|
|
277
|
+
if (entryA.label === entryB.label) return true;
|
|
278
|
+
if (dirtyLabels2.has(entryB.label) && entryA.label > entryB.label) return true;
|
|
279
|
+
return false;
|
|
280
|
+
};
|
|
281
|
+
var detectRedundancy = (entryA, entryB, similarities, redundantSet) => {
|
|
282
|
+
const roleA = entryA.meta.role;
|
|
283
|
+
const roleB = entryB.meta.role;
|
|
284
|
+
if (roleA === "context" /* CONTEXT */ && roleB === "context" /* CONTEXT */) return;
|
|
285
|
+
if (entryA.meta.density < 2 || entryB.meta.density < 2) return;
|
|
286
|
+
if (roleA === "local" /* LOCAL */ && roleB === "context" /* CONTEXT */) {
|
|
287
|
+
redundantSet.add(entryA.label);
|
|
288
|
+
displayRedundancyAlert(entryA.label, entryA.meta, entryB.label, entryB.meta, similarities.max);
|
|
289
|
+
} else if (roleA === "context" /* CONTEXT */ && roleB === "local" /* LOCAL */) {
|
|
290
|
+
redundantSet.add(entryB.label);
|
|
291
|
+
displayRedundancyAlert(entryB.label, entryB.meta, entryA.label, entryA.meta, similarities.max);
|
|
292
|
+
} else if (roleA === "local" /* LOCAL */ && roleB === "local" /* LOCAL */) {
|
|
293
|
+
redundantSet.add(entryA.label);
|
|
294
|
+
redundantSet.add(entryB.label);
|
|
295
|
+
displayRedundancyAlert(entryA.label, entryA.meta, entryB.label, entryB.meta, similarities.max);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
var detectCausalLeak = (entryA, entryB, similarities) => {
|
|
299
|
+
if (entryA.isVolatile || entryB.isVolatile) return;
|
|
300
|
+
if (similarities.bA === similarities.max) {
|
|
301
|
+
displayCausalHint(entryB.label, entryB.meta, entryA.label, entryA.meta);
|
|
302
|
+
} else if (similarities.aB === similarities.max) {
|
|
303
|
+
displayCausalHint(entryA.label, entryA.meta, entryB.label, entryB.meta);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
var detectSubspaceOverlap = (dirtyEntries, allEntries, redundantSet, dirtyLabels2) => {
|
|
307
|
+
let compCount = 0;
|
|
308
|
+
for (const entryA of dirtyEntries) {
|
|
309
|
+
for (const entryB of allEntries) {
|
|
310
|
+
if (shouldSkipComparison(entryA, entryB, dirtyLabels2)) continue;
|
|
311
|
+
compCount++;
|
|
312
|
+
const similarities = calculateAllSimilarities(entryA, entryB);
|
|
313
|
+
if (similarities.max > SIMILARITY_THRESHOLD) {
|
|
314
|
+
detectRedundancy(entryA, entryB, similarities, redundantSet);
|
|
315
|
+
detectCausalLeak(entryA, entryB, similarities);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return compCount;
|
|
320
|
+
};
|
|
321
|
+
|
|
263
322
|
// src/engine.ts
|
|
264
|
-
var
|
|
323
|
+
var BASIS_INSTANCE_KEY = /* @__PURE__ */ Symbol.for("__basis_engine_instance__");
|
|
324
|
+
var NULL_SIGNAL = {
|
|
325
|
+
role: "proj" /* PROJECTION */,
|
|
326
|
+
buffer: new Uint8Array(0),
|
|
327
|
+
head: 0,
|
|
328
|
+
density: 0,
|
|
329
|
+
options: {}
|
|
330
|
+
};
|
|
265
331
|
var getGlobalInstance = () => {
|
|
266
|
-
const
|
|
267
|
-
if (!
|
|
268
|
-
|
|
332
|
+
const root = globalThis;
|
|
333
|
+
if (!root[BASIS_INSTANCE_KEY]) {
|
|
334
|
+
root[BASIS_INSTANCE_KEY] = {
|
|
269
335
|
config: { debug: false },
|
|
270
336
|
history: /* @__PURE__ */ new Map(),
|
|
271
337
|
currentTickBatch: /* @__PURE__ */ new Set(),
|
|
272
338
|
redundantLabels: /* @__PURE__ */ new Set(),
|
|
273
339
|
booted: false,
|
|
274
|
-
updateLog: [],
|
|
275
340
|
tick: 0,
|
|
276
341
|
isBatching: false,
|
|
277
|
-
currentEffectSource: null
|
|
342
|
+
currentEffectSource: null,
|
|
343
|
+
pausedVariables: /* @__PURE__ */ new Set(),
|
|
344
|
+
metrics: {
|
|
345
|
+
lastAnalysisTimeMs: 0,
|
|
346
|
+
comparisonCount: 0,
|
|
347
|
+
lastAnalysisTimestamp: 0,
|
|
348
|
+
systemEntropy: 0
|
|
349
|
+
},
|
|
350
|
+
alertCount: 0,
|
|
351
|
+
loopCounters: /* @__PURE__ */ new Map(),
|
|
352
|
+
lastCleanup: Date.now()
|
|
278
353
|
};
|
|
279
354
|
}
|
|
280
|
-
return
|
|
355
|
+
return root[BASIS_INSTANCE_KEY];
|
|
281
356
|
};
|
|
282
357
|
var instance = getGlobalInstance();
|
|
283
358
|
var config = instance.config;
|
|
284
359
|
var history = instance.history;
|
|
285
|
-
var currentTickBatch = instance.currentTickBatch;
|
|
286
360
|
var redundantLabels = instance.redundantLabels;
|
|
287
|
-
var
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const aFollowsB = calculateSimilarityWithOffset(vecA, vecB, 1, 0, L - 1);
|
|
299
|
-
return { sync, bFollowsA, aFollowsB };
|
|
300
|
-
};
|
|
301
|
-
var getPulseDensity = (vec) => {
|
|
302
|
-
let sum = 0;
|
|
303
|
-
for (let i = 0; i < vec.length; i++) sum += vec[i];
|
|
304
|
-
return sum;
|
|
361
|
+
var currentTickBatch = instance.currentTickBatch;
|
|
362
|
+
var currentTickRegistry = {};
|
|
363
|
+
var dirtyLabels = /* @__PURE__ */ new Set();
|
|
364
|
+
var calculateTickEntropy = (tickIdx) => {
|
|
365
|
+
let activeCount = 0;
|
|
366
|
+
const total = instance.history.size;
|
|
367
|
+
if (total === 0) return 1;
|
|
368
|
+
instance.history.forEach((meta) => {
|
|
369
|
+
if (meta.buffer[tickIdx] === 1) activeCount++;
|
|
370
|
+
});
|
|
371
|
+
return 1 - activeCount / total;
|
|
305
372
|
};
|
|
306
373
|
var analyzeBasis = () => {
|
|
307
|
-
if (!instance.config.debug) {
|
|
308
|
-
instance.redundantLabels.clear();
|
|
374
|
+
if (!instance.config.debug || dirtyLabels.size === 0) {
|
|
309
375
|
return;
|
|
310
376
|
}
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
displayCausalHint(entryA.label, entryB.label, "math");
|
|
336
|
-
}
|
|
377
|
+
const scheduler = globalThis.requestIdleCallback || ((cb) => setTimeout(cb, 1));
|
|
378
|
+
const snapshot = new Set(dirtyLabels);
|
|
379
|
+
dirtyLabels.clear();
|
|
380
|
+
scheduler(() => {
|
|
381
|
+
const analysisStart = performance.now();
|
|
382
|
+
const allEntries = [];
|
|
383
|
+
const dirtyEntries = [];
|
|
384
|
+
instance.history.forEach((meta, label) => {
|
|
385
|
+
if (meta.options.suppressAll || meta.density === 0) return;
|
|
386
|
+
const entry = {
|
|
387
|
+
label,
|
|
388
|
+
meta,
|
|
389
|
+
isVolatile: meta.density > VOLATILITY_THRESHOLD
|
|
390
|
+
};
|
|
391
|
+
allEntries.push(entry);
|
|
392
|
+
if (snapshot.has(label)) {
|
|
393
|
+
dirtyEntries.push(entry);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
if (dirtyEntries.length === 0 || allEntries.length < 2) return;
|
|
397
|
+
const nextRedundant = /* @__PURE__ */ new Set();
|
|
398
|
+
instance.redundantLabels.forEach((l) => {
|
|
399
|
+
if (!snapshot.has(l)) {
|
|
400
|
+
nextRedundant.add(l);
|
|
337
401
|
}
|
|
402
|
+
});
|
|
403
|
+
const compCount = detectSubspaceOverlap(
|
|
404
|
+
dirtyEntries,
|
|
405
|
+
allEntries,
|
|
406
|
+
nextRedundant,
|
|
407
|
+
snapshot
|
|
408
|
+
);
|
|
409
|
+
instance.redundantLabels.clear();
|
|
410
|
+
nextRedundant.forEach((l) => {
|
|
411
|
+
instance.redundantLabels.add(l);
|
|
412
|
+
});
|
|
413
|
+
instance.metrics.lastAnalysisTimeMs = performance.now() - analysisStart;
|
|
414
|
+
instance.metrics.comparisonCount = compCount;
|
|
415
|
+
instance.metrics.lastAnalysisTimestamp = Date.now();
|
|
416
|
+
});
|
|
417
|
+
};
|
|
418
|
+
var processHeartbeat = () => {
|
|
419
|
+
instance.tick++;
|
|
420
|
+
instance.history.forEach((meta, label) => {
|
|
421
|
+
const oldValue = meta.buffer[meta.head];
|
|
422
|
+
const newValue = instance.currentTickBatch.has(label) ? 1 : 0;
|
|
423
|
+
meta.buffer[meta.head] = newValue;
|
|
424
|
+
if (oldValue !== newValue) {
|
|
425
|
+
meta.density += newValue - oldValue;
|
|
338
426
|
}
|
|
427
|
+
meta.head = (meta.head + 1) % WINDOW_SIZE;
|
|
428
|
+
});
|
|
429
|
+
const lastHead = instance.history.size > 0 ? instance.tick % WINDOW_SIZE : 0;
|
|
430
|
+
instance.metrics.systemEntropy = calculateTickEntropy(lastHead);
|
|
431
|
+
instance.currentTickBatch.clear();
|
|
432
|
+
currentTickRegistry = {};
|
|
433
|
+
instance.isBatching = false;
|
|
434
|
+
if (dirtyLabels.size > 0) {
|
|
435
|
+
analyzeBasis();
|
|
339
436
|
}
|
|
340
|
-
instance.redundantLabels.clear();
|
|
341
|
-
newRedundant.forEach((label) => instance.redundantLabels.add(label));
|
|
342
437
|
};
|
|
343
438
|
var recordUpdate = (label) => {
|
|
344
439
|
if (!instance.config.debug) return true;
|
|
440
|
+
if (instance.pausedVariables.has(label)) return false;
|
|
345
441
|
const now = Date.now();
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
instance.
|
|
442
|
+
if (now - instance.lastCleanup > 1e3) {
|
|
443
|
+
instance.loopCounters.clear();
|
|
444
|
+
instance.lastCleanup = now;
|
|
349
445
|
}
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
446
|
+
const count = (instance.loopCounters.get(label) || 0) + 1;
|
|
447
|
+
instance.loopCounters.set(label, count);
|
|
448
|
+
if (count > LOOP_THRESHOLD) {
|
|
449
|
+
displayViolentBreaker(label, count, LOOP_THRESHOLD);
|
|
450
|
+
instance.pausedVariables.add(label);
|
|
353
451
|
return false;
|
|
354
452
|
}
|
|
355
453
|
if (instance.currentEffectSource && instance.currentEffectSource !== label) {
|
|
356
|
-
|
|
454
|
+
const targetMeta = instance.history.get(label);
|
|
455
|
+
const sourceMeta = instance.history.get(instance.currentEffectSource);
|
|
456
|
+
if (targetMeta) {
|
|
457
|
+
const sourceDensity = sourceMeta?.density || 0;
|
|
458
|
+
const isVolatile = targetMeta.density > VOLATILITY_THRESHOLD || sourceDensity > VOLATILITY_THRESHOLD;
|
|
459
|
+
if (!isVolatile) {
|
|
460
|
+
displayCausalHint(label, targetMeta, instance.currentEffectSource, sourceMeta || NULL_SIGNAL);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
357
463
|
}
|
|
464
|
+
if (currentTickRegistry[label]) return true;
|
|
465
|
+
currentTickRegistry[label] = true;
|
|
358
466
|
instance.currentTickBatch.add(label);
|
|
467
|
+
dirtyLabels.add(label);
|
|
359
468
|
if (!instance.isBatching) {
|
|
360
469
|
instance.isBatching = true;
|
|
361
|
-
|
|
362
|
-
instance.tick++;
|
|
363
|
-
instance.history.forEach((vec, l) => {
|
|
364
|
-
vec.shift();
|
|
365
|
-
vec.push(instance.currentTickBatch.has(l) ? 1 : 0);
|
|
366
|
-
});
|
|
367
|
-
instance.currentTickBatch.clear();
|
|
368
|
-
instance.isBatching = false;
|
|
369
|
-
if (instance.tick % ANALYSIS_INTERVAL === 0) {
|
|
370
|
-
analyzeBasis();
|
|
371
|
-
}
|
|
372
|
-
}, 20);
|
|
470
|
+
requestAnimationFrame(processHeartbeat);
|
|
373
471
|
}
|
|
374
472
|
return true;
|
|
375
473
|
};
|
|
376
|
-
var
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
474
|
+
var configureBasis = (c) => {
|
|
475
|
+
Object.assign(instance.config, c);
|
|
476
|
+
if (instance.config.debug && !instance.booted) {
|
|
477
|
+
displayBootLog(WINDOW_SIZE);
|
|
478
|
+
instance.booted = true;
|
|
479
|
+
}
|
|
381
480
|
};
|
|
382
|
-
var registerVariable = (
|
|
383
|
-
if (!instance.config.debug) return;
|
|
384
|
-
if (!instance.history.has(
|
|
385
|
-
instance.history.set(
|
|
481
|
+
var registerVariable = (l, o = {}) => {
|
|
482
|
+
if (!instance.config.debug || o.suppressAll) return;
|
|
483
|
+
if (!instance.history.has(l)) {
|
|
484
|
+
instance.history.set(l, {
|
|
485
|
+
buffer: new Uint8Array(WINDOW_SIZE),
|
|
486
|
+
head: 0,
|
|
487
|
+
density: 0,
|
|
488
|
+
options: o,
|
|
489
|
+
role: o.role || "local" /* LOCAL */
|
|
490
|
+
});
|
|
386
491
|
}
|
|
387
492
|
};
|
|
388
|
-
var unregisterVariable = (
|
|
389
|
-
instance.history.delete(
|
|
493
|
+
var unregisterVariable = (l) => {
|
|
494
|
+
instance.history.delete(l);
|
|
495
|
+
instance.loopCounters.delete(l);
|
|
496
|
+
instance.pausedVariables.delete(l);
|
|
497
|
+
instance.redundantLabels.delete(l);
|
|
498
|
+
};
|
|
499
|
+
var beginEffectTracking = (l) => {
|
|
500
|
+
if (instance.config.debug) instance.currentEffectSource = l;
|
|
501
|
+
};
|
|
502
|
+
var endEffectTracking = () => {
|
|
503
|
+
instance.currentEffectSource = null;
|
|
390
504
|
};
|
|
391
505
|
var printBasisHealthReport = (threshold = 0.5) => {
|
|
392
|
-
if (!instance.config.debug)
|
|
393
|
-
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
displayHealthReport(instance.history, calculateCosineSimilarity, threshold);
|
|
506
|
+
if (!instance.config.debug) return;
|
|
507
|
+
displayHealthReport(instance.history, threshold);
|
|
397
508
|
};
|
|
509
|
+
var getBasisMetrics = () => ({
|
|
510
|
+
engine: "v0.5.x",
|
|
511
|
+
hooks: instance.history.size,
|
|
512
|
+
analysis_ms: instance.metrics.lastAnalysisTimeMs.toFixed(3),
|
|
513
|
+
entropy: instance.metrics.systemEntropy.toFixed(3)
|
|
514
|
+
});
|
|
398
515
|
if (typeof window !== "undefined") {
|
|
399
516
|
window.printBasisReport = printBasisHealthReport;
|
|
517
|
+
window.getBasisMetrics = getBasisMetrics;
|
|
400
518
|
}
|
|
401
|
-
var __testEngine__ = {
|
|
402
|
-
instance,
|
|
403
|
-
config: instance.config,
|
|
404
|
-
history: instance.history,
|
|
405
|
-
currentTickBatch: instance.currentTickBatch,
|
|
406
|
-
configureBasis,
|
|
407
|
-
registerVariable,
|
|
408
|
-
recordUpdate,
|
|
409
|
-
printBasisHealthReport,
|
|
410
|
-
beginEffectTracking,
|
|
411
|
-
endEffectTracking
|
|
412
|
-
};
|
|
413
519
|
|
|
414
520
|
// src/hooks.ts
|
|
415
521
|
var anonCount = 0;
|
|
416
522
|
var getFallbackLabel = (type) => `anon_${type}_${anonCount++}`;
|
|
523
|
+
var React19 = React;
|
|
417
524
|
function useState(initialState, label) {
|
|
418
525
|
const [val, setVal] = (0, import_react.useState)(initialState);
|
|
419
526
|
const effectiveLabel = (0, import_react.useRef)(label || getFallbackLabel("state")).current;
|
|
420
527
|
(0, import_react.useEffect)(() => {
|
|
421
|
-
registerVariable(effectiveLabel);
|
|
422
|
-
return () =>
|
|
528
|
+
registerVariable(effectiveLabel, { role: "local" /* LOCAL */ });
|
|
529
|
+
return () => {
|
|
530
|
+
unregisterVariable(effectiveLabel);
|
|
531
|
+
};
|
|
423
532
|
}, [effectiveLabel]);
|
|
424
|
-
const setter = (0, import_react.useCallback)((
|
|
533
|
+
const setter = (0, import_react.useCallback)((value) => {
|
|
425
534
|
if (recordUpdate(effectiveLabel)) {
|
|
426
|
-
setVal(
|
|
535
|
+
setVal(value);
|
|
427
536
|
}
|
|
428
537
|
}, [effectiveLabel]);
|
|
429
538
|
return [val, setter];
|
|
430
539
|
}
|
|
431
|
-
function useRef(initialValue, _label) {
|
|
432
|
-
return (0, import_react.useRef)(initialValue);
|
|
433
|
-
}
|
|
434
540
|
function useReducer(reducer, initialArg, init, label) {
|
|
435
|
-
const
|
|
436
|
-
const providedLabel =
|
|
541
|
+
const isLazy = typeof init === "function";
|
|
542
|
+
const providedLabel = label || (typeof init === "string" ? init : void 0);
|
|
437
543
|
const effectiveLabel = (0, import_react.useRef)(providedLabel || getFallbackLabel("reducer")).current;
|
|
438
|
-
const [state, dispatch] = (0, import_react.useReducer)(
|
|
439
|
-
reducer,
|
|
440
|
-
initialArg,
|
|
441
|
-
isLazyInit ? init : void 0
|
|
442
|
-
);
|
|
544
|
+
const [state, dispatch] = isLazy ? (0, import_react.useReducer)(reducer, initialArg, init) : (0, import_react.useReducer)(reducer, initialArg);
|
|
443
545
|
(0, import_react.useEffect)(() => {
|
|
444
|
-
registerVariable(effectiveLabel);
|
|
445
|
-
return () =>
|
|
546
|
+
registerVariable(effectiveLabel, { role: "local" /* LOCAL */ });
|
|
547
|
+
return () => {
|
|
548
|
+
unregisterVariable(effectiveLabel);
|
|
549
|
+
};
|
|
446
550
|
}, [effectiveLabel]);
|
|
447
551
|
const basisDispatch = (0, import_react.useCallback)((action) => {
|
|
448
552
|
if (recordUpdate(effectiveLabel)) {
|
|
449
553
|
dispatch(action);
|
|
450
554
|
}
|
|
451
|
-
}, [effectiveLabel]);
|
|
555
|
+
}, [effectiveLabel, dispatch]);
|
|
452
556
|
return [state, basisDispatch];
|
|
453
557
|
}
|
|
558
|
+
function createContext(defaultValue, label) {
|
|
559
|
+
const context = (0, import_react.createContext)(defaultValue);
|
|
560
|
+
const effectiveLabel = label || getFallbackLabel("context");
|
|
561
|
+
Object.defineProperty(context, "_basis_label", {
|
|
562
|
+
value: effectiveLabel,
|
|
563
|
+
writable: false,
|
|
564
|
+
enumerable: false
|
|
565
|
+
});
|
|
566
|
+
return context;
|
|
567
|
+
}
|
|
568
|
+
function useContext(context) {
|
|
569
|
+
const val = (0, import_react.useContext)(context);
|
|
570
|
+
const label = context._basis_label;
|
|
571
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
572
|
+
if (label) {
|
|
573
|
+
registerVariable(label, { role: "context" /* CONTEXT */ });
|
|
574
|
+
recordUpdate(label);
|
|
575
|
+
}
|
|
576
|
+
}, [val, label]);
|
|
577
|
+
return val;
|
|
578
|
+
}
|
|
454
579
|
function useMemo(factory, deps, label) {
|
|
455
|
-
const effectiveLabel = label || "
|
|
580
|
+
const effectiveLabel = (0, import_react.useRef)(label || getFallbackLabel("proj")).current;
|
|
456
581
|
(0, import_react.useEffect)(() => {
|
|
457
|
-
|
|
582
|
+
registerVariable(effectiveLabel, { role: "proj" /* PROJECTION */ });
|
|
583
|
+
return () => {
|
|
584
|
+
unregisterVariable(effectiveLabel);
|
|
585
|
+
};
|
|
458
586
|
}, [effectiveLabel]);
|
|
459
587
|
return (0, import_react.useMemo)(factory, deps || []);
|
|
460
588
|
}
|
|
461
589
|
function useCallback(callback, deps, label) {
|
|
462
|
-
const effectiveLabel = label || "
|
|
590
|
+
const effectiveLabel = (0, import_react.useRef)(label || getFallbackLabel("cb")).current;
|
|
463
591
|
(0, import_react.useEffect)(() => {
|
|
464
|
-
|
|
592
|
+
registerVariable(effectiveLabel, { role: "proj" /* PROJECTION */ });
|
|
593
|
+
return () => {
|
|
594
|
+
unregisterVariable(effectiveLabel);
|
|
595
|
+
};
|
|
465
596
|
}, [effectiveLabel]);
|
|
466
597
|
return (0, import_react.useCallback)(callback, deps);
|
|
467
598
|
}
|
|
@@ -469,54 +600,29 @@ function useEffect(effect, deps, label) {
|
|
|
469
600
|
const effectiveLabel = label || "anonymous_effect";
|
|
470
601
|
(0, import_react.useEffect)(() => {
|
|
471
602
|
beginEffectTracking(effectiveLabel);
|
|
472
|
-
const
|
|
603
|
+
const destructor = effect();
|
|
473
604
|
endEffectTracking();
|
|
474
|
-
return
|
|
605
|
+
return typeof destructor === "function" ? destructor : void 0;
|
|
475
606
|
}, deps);
|
|
476
607
|
}
|
|
477
608
|
function useLayoutEffect(effect, deps, label) {
|
|
478
609
|
const effectiveLabel = label || "anonymous_layout_effect";
|
|
479
610
|
(0, import_react.useLayoutEffect)(() => {
|
|
480
611
|
beginEffectTracking(effectiveLabel);
|
|
481
|
-
const
|
|
612
|
+
const destructor = effect();
|
|
482
613
|
endEffectTracking();
|
|
483
|
-
return
|
|
614
|
+
return typeof destructor === "function" ? destructor : void 0;
|
|
484
615
|
}, deps);
|
|
485
616
|
}
|
|
486
|
-
function
|
|
487
|
-
const
|
|
488
|
-
const effectiveLabel = _label || "anonymous_transition";
|
|
489
|
-
const basisStartTransition = (callback) => {
|
|
490
|
-
if (config.debug) console.log(`%c [Basis] Transition Started: "${effectiveLabel}" `, "color: #e67e22; font-weight: bold;");
|
|
491
|
-
startTransition(callback);
|
|
492
|
-
};
|
|
493
|
-
return [isPending, basisStartTransition];
|
|
494
|
-
}
|
|
495
|
-
function useDeferredValue(value, initialValueOrLabel, label) {
|
|
496
|
-
const isLabelAsSecondArg = typeof initialValueOrLabel === "string" && label === void 0;
|
|
497
|
-
const actualInitialValue = isLabelAsSecondArg ? void 0 : initialValueOrLabel;
|
|
498
|
-
const effectiveLabel = isLabelAsSecondArg ? initialValueOrLabel : label || "anonymous_deferred";
|
|
499
|
-
const deferredValue = (0, import_react.useDeferredValue)(value, actualInitialValue);
|
|
500
|
-
(0, import_react.useEffect)(() => {
|
|
501
|
-
if (config.debug && value !== deferredValue) console.log(`%c [Basis] Value Deferred: "${effectiveLabel}" `, "color: #e67e22; font-weight: bold;");
|
|
502
|
-
}, [value, deferredValue, effectiveLabel]);
|
|
503
|
-
return deferredValue;
|
|
504
|
-
}
|
|
505
|
-
var useId2 = (label) => React.useId();
|
|
506
|
-
var useDebugValue2 = React.useDebugValue;
|
|
507
|
-
var useImperativeHandle2 = React.useImperativeHandle;
|
|
508
|
-
var useInsertionEffect2 = React.useInsertionEffect;
|
|
509
|
-
var useSyncExternalStore = import_react.useSyncExternalStore;
|
|
510
|
-
function use(usable) {
|
|
511
|
-
return (0, import_react.use)(usable);
|
|
512
|
-
}
|
|
513
|
-
function useOptimistic2(passthrough, reducer, label) {
|
|
514
|
-
const effectiveLabel = label || "anonymous_optimistic";
|
|
617
|
+
function useOptimistic(passthrough, reducer, label) {
|
|
618
|
+
const effectiveLabel = (0, import_react.useRef)(label || getFallbackLabel("optimistic")).current;
|
|
515
619
|
(0, import_react.useEffect)(() => {
|
|
516
|
-
registerVariable(effectiveLabel);
|
|
517
|
-
return () =>
|
|
620
|
+
registerVariable(effectiveLabel, { role: "local" /* LOCAL */ });
|
|
621
|
+
return () => {
|
|
622
|
+
unregisterVariable(effectiveLabel);
|
|
623
|
+
};
|
|
518
624
|
}, [effectiveLabel]);
|
|
519
|
-
const [state, reactAddOptimistic] =
|
|
625
|
+
const [state, reactAddOptimistic] = React19.useOptimistic(passthrough, reducer);
|
|
520
626
|
const addOptimistic = (0, import_react.useCallback)((payload) => {
|
|
521
627
|
if (recordUpdate(effectiveLabel)) {
|
|
522
628
|
reactAddOptimistic(payload);
|
|
@@ -524,18 +630,16 @@ function useOptimistic2(passthrough, reducer, label) {
|
|
|
524
630
|
}, [effectiveLabel, reactAddOptimistic]);
|
|
525
631
|
return [state, addOptimistic];
|
|
526
632
|
}
|
|
527
|
-
function
|
|
528
|
-
const
|
|
529
|
-
const
|
|
530
|
-
const
|
|
531
|
-
const [state, reactDispatch, isPending] =
|
|
532
|
-
action,
|
|
533
|
-
initialState,
|
|
534
|
-
actualPermalink
|
|
535
|
-
);
|
|
633
|
+
function useActionState(action, initialState, permalink, label) {
|
|
634
|
+
const isLabelArg = typeof permalink === "string" && label === void 0;
|
|
635
|
+
const effectiveLabel = (0, import_react.useRef)(isLabelArg ? permalink : label || getFallbackLabel("action_state")).current;
|
|
636
|
+
const actualPermalink = isLabelArg ? void 0 : permalink;
|
|
637
|
+
const [state, reactDispatch, isPending] = React19.useActionState(action, initialState, actualPermalink);
|
|
536
638
|
(0, import_react.useEffect)(() => {
|
|
537
|
-
registerVariable(effectiveLabel);
|
|
538
|
-
return () =>
|
|
639
|
+
registerVariable(effectiveLabel, { role: "local" /* LOCAL */ });
|
|
640
|
+
return () => {
|
|
641
|
+
unregisterVariable(effectiveLabel);
|
|
642
|
+
};
|
|
539
643
|
}, [effectiveLabel]);
|
|
540
644
|
const basisDispatch = (0, import_react.useCallback)((payload) => {
|
|
541
645
|
if (recordUpdate(effectiveLabel)) {
|
|
@@ -544,6 +648,15 @@ function useActionState2(action, initialState, permalink, label) {
|
|
|
544
648
|
}, [effectiveLabel, reactDispatch]);
|
|
545
649
|
return [state, basisDispatch, isPending];
|
|
546
650
|
}
|
|
651
|
+
var useRef = import_react.useRef;
|
|
652
|
+
var useId2 = React.useId;
|
|
653
|
+
var useDebugValue2 = React.useDebugValue;
|
|
654
|
+
var useImperativeHandle2 = React.useImperativeHandle;
|
|
655
|
+
var useInsertionEffect2 = React.useInsertionEffect;
|
|
656
|
+
var useSyncExternalStore = import_react.useSyncExternalStore;
|
|
657
|
+
var useTransition = import_react.useTransition;
|
|
658
|
+
var useDeferredValue = import_react.useDeferredValue;
|
|
659
|
+
var use = React19.use;
|
|
547
660
|
|
|
548
661
|
// src/context.tsx
|
|
549
662
|
var import_react3 = require("react");
|
|
@@ -595,8 +708,15 @@ var BasisHUD = () => {
|
|
|
595
708
|
const canvasRef = (0, import_react2.useRef)(null);
|
|
596
709
|
(0, import_react2.useEffect)(() => {
|
|
597
710
|
if (!isExpanded) return;
|
|
598
|
-
let
|
|
711
|
+
let isMounted = true;
|
|
712
|
+
let animationFrame = null;
|
|
599
713
|
const draw = () => {
|
|
714
|
+
if (!isMounted) {
|
|
715
|
+
if (animationFrame !== null) {
|
|
716
|
+
cancelAnimationFrame(animationFrame);
|
|
717
|
+
}
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
600
720
|
const canvas = canvasRef.current;
|
|
601
721
|
if (!canvas) return;
|
|
602
722
|
const ctx = canvas.getContext("2d");
|
|
@@ -604,28 +724,27 @@ var BasisHUD = () => {
|
|
|
604
724
|
const entries = Array.from(history.entries());
|
|
605
725
|
const dpr = window.devicePixelRatio || 1;
|
|
606
726
|
const rawWidth = HUD_DIMENSIONS.WINDOW_SIZE * HUD_DIMENSIONS.COL_WIDTH + HUD_DIMENSIONS.LABEL_WIDTH + HUD_DIMENSIONS.PADDING * 2;
|
|
607
|
-
const rawHeight = Math.max(entries.length * HUD_DIMENSIONS.ROW_HEIGHT + HUD_DIMENSIONS.PADDING * 2,
|
|
727
|
+
const rawHeight = Math.max(entries.length * HUD_DIMENSIONS.ROW_HEIGHT + HUD_DIMENSIONS.PADDING * 2, 80);
|
|
608
728
|
updateCanvasSize(canvas, rawWidth, rawHeight, dpr);
|
|
609
729
|
ctx.save();
|
|
610
730
|
ctx.scale(dpr, dpr);
|
|
611
731
|
ctx.clearRect(0, 0, rawWidth, rawHeight);
|
|
612
|
-
if (entries.length === 0)
|
|
613
|
-
|
|
614
|
-
} else {
|
|
615
|
-
renderMatrix(ctx, entries);
|
|
616
|
-
}
|
|
732
|
+
if (entries.length === 0) renderEmptyState(ctx);
|
|
733
|
+
else renderMatrix(ctx, entries);
|
|
617
734
|
ctx.restore();
|
|
618
735
|
animationFrame = requestAnimationFrame(draw);
|
|
619
736
|
};
|
|
620
|
-
draw
|
|
621
|
-
return () =>
|
|
737
|
+
animationFrame = requestAnimationFrame(draw);
|
|
738
|
+
return () => {
|
|
739
|
+
isMounted = false;
|
|
740
|
+
if (animationFrame !== null) {
|
|
741
|
+
cancelAnimationFrame(animationFrame);
|
|
742
|
+
}
|
|
743
|
+
};
|
|
622
744
|
}, [isExpanded]);
|
|
623
745
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: getHUDContainerStyle(isExpanded), onClick: () => setIsExpanded(!isExpanded), children: [
|
|
624
746
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(HUDHeader, { isExpanded }),
|
|
625
|
-
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime.
|
|
626
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("canvas", { ref: canvasRef, style: { display: "block" } }),
|
|
627
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(HUDFooter, {})
|
|
628
|
-
] })
|
|
747
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "10px 14px 15px 14px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("canvas", { ref: canvasRef, style: { display: "block" } }) })
|
|
629
748
|
] });
|
|
630
749
|
};
|
|
631
750
|
function updateCanvasSize(canvas, w, h, dpr) {
|
|
@@ -644,63 +763,72 @@ function renderEmptyState(ctx) {
|
|
|
644
763
|
ctx.fillText("Waiting for state transitions...", HUD_DIMENSIONS.PADDING, 30);
|
|
645
764
|
}
|
|
646
765
|
function renderMatrix(ctx, entries) {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
766
|
+
const L = HUD_DIMENSIONS.WINDOW_SIZE;
|
|
767
|
+
const colW = HUD_DIMENSIONS.COL_WIDTH;
|
|
768
|
+
const rowH = HUD_DIMENSIONS.ROW_HEIGHT;
|
|
769
|
+
const pad = HUD_DIMENSIONS.PADDING;
|
|
770
|
+
const cellW = colW - 1.5;
|
|
771
|
+
const cellH = rowH - 4;
|
|
772
|
+
const gridPath = new Path2D();
|
|
773
|
+
const successPath = new Path2D();
|
|
774
|
+
const contextPath = new Path2D();
|
|
775
|
+
const errorPath = new Path2D();
|
|
776
|
+
ctx.font = "11px Inter, Menlo, monospace";
|
|
777
|
+
let rowIndex = 0;
|
|
778
|
+
for (const [label, meta] of entries) {
|
|
779
|
+
const y = rowIndex * rowH + pad;
|
|
780
|
+
const isContext = meta.role === "context";
|
|
781
|
+
const isRedundant = !isContext && redundantLabels.has(label);
|
|
782
|
+
const { buffer, head } = meta;
|
|
783
|
+
let uiPos = 0;
|
|
784
|
+
const addToPath = (val, xIdx) => {
|
|
785
|
+
const x = xIdx * colW + pad;
|
|
786
|
+
if (val === 1) {
|
|
787
|
+
if (isContext) contextPath.rect(x, y, cellW, cellH);
|
|
788
|
+
else if (isRedundant) errorPath.rect(x, y, cellW, cellH);
|
|
789
|
+
else successPath.rect(x, y, cellW, cellH);
|
|
662
790
|
} else {
|
|
663
|
-
|
|
791
|
+
gridPath.rect(x, y, cellW, cellH);
|
|
664
792
|
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
793
|
+
};
|
|
794
|
+
for (let i = head; i < L; i++) addToPath(buffer[i], uiPos++);
|
|
795
|
+
for (let i = 0; i < head; i++) addToPath(buffer[i], uiPos++);
|
|
796
|
+
const stateName = label.split(" -> ")[1] || label;
|
|
797
|
+
const textX = L * colW + pad + 10;
|
|
798
|
+
ctx.fillStyle = isContext ? HUD_THEME.header : isRedundant ? HUD_THEME.error : HUD_THEME.text;
|
|
799
|
+
ctx.fillText((isContext ? "\u03A9 " : isRedundant ? "! " : "") + stateName, textX, y + 9);
|
|
800
|
+
rowIndex++;
|
|
801
|
+
}
|
|
802
|
+
ctx.fillStyle = HUD_THEME.grid;
|
|
803
|
+
ctx.fill(gridPath);
|
|
804
|
+
ctx.fillStyle = HUD_THEME.success;
|
|
805
|
+
ctx.fill(successPath);
|
|
806
|
+
ctx.fillStyle = HUD_THEME.header;
|
|
807
|
+
ctx.fill(contextPath);
|
|
808
|
+
ctx.fillStyle = HUD_THEME.error;
|
|
809
|
+
ctx.fill(errorPath);
|
|
676
810
|
}
|
|
677
|
-
var HUDHeader = ({ isExpanded }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
display: "flex",
|
|
699
|
-
justifyContent: "space-between"
|
|
700
|
-
}, children: [
|
|
701
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "LINEAR DEPENDENCY AUDIT" }),
|
|
702
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "THRESHOLD 0.88" })
|
|
703
|
-
] });
|
|
811
|
+
var HUDHeader = ({ isExpanded }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
812
|
+
"div",
|
|
813
|
+
{
|
|
814
|
+
style: {
|
|
815
|
+
padding: "10px 14px",
|
|
816
|
+
backgroundColor: isExpanded ? HUD_THEME.header : "transparent",
|
|
817
|
+
color: isExpanded ? "white" : HUD_THEME.header,
|
|
818
|
+
fontWeight: 600,
|
|
819
|
+
fontSize: "11px",
|
|
820
|
+
letterSpacing: "0.05em",
|
|
821
|
+
display: "flex",
|
|
822
|
+
justifyContent: "space-between",
|
|
823
|
+
alignItems: "center",
|
|
824
|
+
transition: "background 0.3s"
|
|
825
|
+
},
|
|
826
|
+
children: [
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: isExpanded ? "STATE BASIS MATRIX" : "\u{1F4D0} BASIS ACTIVE" }),
|
|
828
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { opacity: 0.8, fontSize: "9px" }, children: "v0.5.x" })
|
|
829
|
+
]
|
|
830
|
+
}
|
|
831
|
+
);
|
|
704
832
|
|
|
705
833
|
// src/context.tsx
|
|
706
834
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -738,11 +866,14 @@ function basis() {
|
|
|
738
866
|
BasisProvider,
|
|
739
867
|
basis,
|
|
740
868
|
configureBasis,
|
|
869
|
+
createContext,
|
|
870
|
+
getBasisMetrics,
|
|
741
871
|
printBasisHealthReport,
|
|
742
872
|
use,
|
|
743
873
|
useActionState,
|
|
744
874
|
useBasisConfig,
|
|
745
875
|
useCallback,
|
|
876
|
+
useContext,
|
|
746
877
|
useDebugValue,
|
|
747
878
|
useDeferredValue,
|
|
748
879
|
useEffect,
|