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/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: () => useActionState2,
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: () => useOptimistic2,
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 = 5e3;
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 displayBootLog = (windowSize) => {
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
- console.group(`%c \u{1F4D0} BASIS | REDUNDANT PATTERN `, STYLES.headerRed);
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
- console.log(
113
- `%cObservation:%c %c${infoA.name}%c and %c${infoB.name}%c move together.
114
- %cOne is likely a direct mirror of the other. Confidence: ${(sim * 100).toFixed(0)}%`,
115
- STYLES.bold,
116
- "",
117
- STYLES.label,
118
- "",
119
- STYLES.label,
120
- "",
121
- STYLES.subText
122
- );
123
- console.log(
124
- `%cAction:%c Refactor %c${infoB.name}%c to useMemo.`,
125
- "color: #00b894; font-weight: bold;",
126
- "",
127
- "color: #e84393; font-weight: bold;",
128
- ""
129
- );
130
- console.groupEnd();
131
- };
132
- var displayCausalHint = (targetLabel, sourceLabel, method = "math") => {
133
- const key = `causal-${sourceLabel}-${targetLabel}`;
134
- if (!isWeb || !shouldLog(key)) return;
135
- const target = parseLabel(targetLabel);
136
- const source = parseLabel(sourceLabel);
137
- console.groupCollapsed(
138
- `%c \u{1F4A1} BASIS | ${method === "math" ? "DETECTED" : "TRACKED"} SYNC LEAK `,
139
- STYLES.headerBlue
140
- );
141
- console.log(`%c\u{1F4CD} Location: %c${target.file}`, STYLES.bold, STYLES.location);
142
- console.log(
143
- `%cFlow:%c %c${source.name}%c \u2794 Effect \u2794 %c${target.name}%c`,
144
- STYLES.bold,
145
- "",
146
- STYLES.label,
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 displayInfiniteLoop = (label) => {
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, vecA]) => {
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, vecB]) => {
182
+ entries.forEach(([labelB, metaB]) => {
182
183
  if (labelA === labelB || processed.has(labelB)) return;
183
- const sim = similarityFn(vecA, vecB);
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
- clusters.push(currentCluster);
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
- if (isWeb) {
198
- console.group(`%c \u{1F4CA} BASIS | ARCHITECTURAL HEALTH REPORT `, STYLES.headerGreen);
199
- console.log(
200
- `%cArchitectural Health Score: %c${healthScore.toFixed(1)}% %c(State Distribution: ${systemRank}/${totalVars})`,
201
- STYLES.bold,
202
- `color: ${healthScore > 85 ? "#00b894" : "#d63031"}; font-size: 16px; font-weight: bold;`,
203
- "color: #636e72; font-style: italic;"
204
- );
205
- if (clusters.length > 0) {
206
- console.log(`%cDetected ${clusters.length} Synchronized Update Clusters:`, "font-weight: bold; color: #e17055; margin-top: 10px;");
207
- clusters.forEach((cluster, idx) => {
208
- const names = cluster.map((l) => parseLabel(l).name).join(" \u27F7 ");
209
- console.log(` %c${idx + 1}%c ${names}`, "background: #e17055; color: white; border-radius: 50%; padding: 0 5px;", "font-family: monospace;");
210
- });
211
- console.log("%c\u{1F4A1} Action: Variables in a cluster move together. Try refactoring them into a single state object or use useMemo for derived values.", STYLES.subText);
212
- } else {
213
- console.log("%c\u2728 All state variables have optimal distribution. Your Basis is healthy.", "color: #00b894; font-weight: bold; margin-top: 10px;");
214
- }
215
- if (totalVars > 0 && totalVars < 15) {
216
- console.groupCollapsed("%cView Full Correlation Matrix", "color: #636e72; font-size: 11px;");
217
- const matrix = {};
218
- entries.forEach(([labelA]) => {
219
- const nameA = parseLabel(labelA).name;
220
- matrix[nameA] = {};
221
- entries.forEach(([labelB]) => {
222
- const nameB = parseLabel(labelB).name;
223
- const sim = similarityFn(history2.get(labelA), history2.get(labelB));
224
- matrix[nameA][nameB] = sim > threshold ? `\u274C ${(sim * 100).toFixed(0)}%` : `\u2705`;
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(`[BASIS HEALTH] Score: ${healthScore.toFixed(1)}% (State Distribution: ${systemRank}/${totalVars})`);
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
- // src/core/math.ts
237
- var calculateSimilarityWithOffset = (A, B, offsetA, offsetB, length) => {
238
- let dot = 0;
239
- let magA = 0;
240
- let magB = 0;
241
- for (let i = 0; i < length; i++) {
242
- const valA = A[i + offsetA];
243
- const valB = B[i + offsetB];
244
- dot += valA * valB;
245
- magA += valA * valA;
246
- magB += valB * valB;
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
- if (magA === 0 || magB === 0) return 0;
249
- return dot / (Math.sqrt(magA) * Math.sqrt(magB));
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 calculateCosineSimilarity = (A, B) => {
252
- return calculateSimilarityWithOffset(A, B, 0, 0, A.length);
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 GLOBAL_KEY = "__BASIS_ENGINE_INSTANCE__";
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 g = typeof window !== "undefined" ? window : global;
267
- if (!g[GLOBAL_KEY]) {
268
- g[GLOBAL_KEY] = {
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 g[GLOBAL_KEY];
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 configureBasis = (newConfig) => {
288
- Object.assign(instance.config, newConfig);
289
- if (instance.config.debug && !instance.booted) {
290
- displayBootLog(WINDOW_SIZE);
291
- instance.booted = true;
292
- }
293
- };
294
- var getTemporalSimilarity = (vecA, vecB) => {
295
- const L = vecA.length;
296
- const sync = calculateSimilarityWithOffset(vecA, vecB, 0, 0, L);
297
- const bFollowsA = calculateSimilarityWithOffset(vecA, vecB, 0, 1, L - 1);
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 entries = Array.from(instance.history.entries()).map(([label, vec]) => ({
312
- label,
313
- vec,
314
- density: getPulseDensity(vec)
315
- })).filter((e) => e.density >= 2);
316
- if (entries.length < 2) return;
317
- const newRedundant = /* @__PURE__ */ new Set();
318
- for (let i = 0; i < entries.length; i++) {
319
- for (let j = i + 1; j < entries.length; j++) {
320
- const entryA = entries[i];
321
- const entryB = entries[j];
322
- const { sync, bFollowsA, aFollowsB } = getTemporalSimilarity(entryA.vec, entryB.vec);
323
- const maxSim = Math.max(sync, bFollowsA, aFollowsB);
324
- if (maxSim > SIMILARITY_THRESHOLD) {
325
- const isBothVolatile = entryA.density > VOLATILITY_THRESHOLD && entryB.density > VOLATILITY_THRESHOLD;
326
- if (sync === maxSim) {
327
- if (!isBothVolatile) {
328
- newRedundant.add(entryA.label);
329
- newRedundant.add(entryB.label);
330
- displayRedundancyAlert(entryA.label, entryB.label, sync);
331
- }
332
- } else if (bFollowsA === maxSim) {
333
- displayCausalHint(entryB.label, entryA.label, "math");
334
- } else if (aFollowsB === maxSim) {
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
- instance.updateLog.push({ label, ts: now });
347
- if (instance.updateLog.length > 200) {
348
- instance.updateLog = instance.updateLog.filter((e) => now - e.ts < LOOP_WINDOW_MS);
442
+ if (now - instance.lastCleanup > 1e3) {
443
+ instance.loopCounters.clear();
444
+ instance.lastCleanup = now;
349
445
  }
350
- const updateCount = instance.updateLog.filter((e) => e.label === label).length;
351
- if (updateCount > LOOP_THRESHOLD) {
352
- displayInfiniteLoop(label);
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
- displayCausalHint(label, instance.currentEffectSource, "tracking");
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
- setTimeout(() => {
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 beginEffectTracking = (label) => {
377
- if (instance.config.debug) instance.currentEffectSource = label;
378
- };
379
- var endEffectTracking = () => {
380
- instance.currentEffectSource = null;
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 = (label) => {
383
- if (!instance.config.debug) return;
384
- if (!instance.history.has(label)) {
385
- instance.history.set(label, new Array(WINDOW_SIZE).fill(0));
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 = (label) => {
389
- instance.history.delete(label);
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
- console.warn("[Basis] Cannot generate report. Debug mode is OFF.");
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 () => unregisterVariable(effectiveLabel);
528
+ registerVariable(effectiveLabel, { role: "local" /* LOCAL */ });
529
+ return () => {
530
+ unregisterVariable(effectiveLabel);
531
+ };
423
532
  }, [effectiveLabel]);
424
- const setter = (0, import_react.useCallback)((newValue) => {
533
+ const setter = (0, import_react.useCallback)((value) => {
425
534
  if (recordUpdate(effectiveLabel)) {
426
- setVal(newValue);
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 isLazyInit = typeof init === "function";
436
- const providedLabel = isLazyInit ? label : typeof init === "string" ? init : void 0;
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 () => unregisterVariable(effectiveLabel);
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 || "anonymous_projection";
580
+ const effectiveLabel = (0, import_react.useRef)(label || getFallbackLabel("proj")).current;
456
581
  (0, import_react.useEffect)(() => {
457
- if (config.debug) console.log(`%c [Basis] Valid Projection: "${effectiveLabel}" `, "color: #2ecc71; font-weight: bold;");
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 || "anonymous_callback";
590
+ const effectiveLabel = (0, import_react.useRef)(label || getFallbackLabel("cb")).current;
463
591
  (0, import_react.useEffect)(() => {
464
- if (config.debug) console.log(`%c [Basis] Stable Callback: "${effectiveLabel}" `, "color: #2ecc71; font-weight: bold;");
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 cleanup = effect();
603
+ const destructor = effect();
473
604
  endEffectTracking();
474
- return cleanup;
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 cleanup = effect();
612
+ const destructor = effect();
482
613
  endEffectTracking();
483
- return cleanup;
614
+ return typeof destructor === "function" ? destructor : void 0;
484
615
  }, deps);
485
616
  }
486
- function useTransition(_label) {
487
- const [isPending, startTransition] = (0, import_react.useTransition)();
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 () => unregisterVariable(effectiveLabel);
620
+ registerVariable(effectiveLabel, { role: "local" /* LOCAL */ });
621
+ return () => {
622
+ unregisterVariable(effectiveLabel);
623
+ };
518
624
  }, [effectiveLabel]);
519
- const [state, reactAddOptimistic] = React.useOptimistic(passthrough, reducer);
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 useActionState2(action, initialState, permalink, label) {
528
- const isLabelAsThirdArg = typeof permalink === "string" && label === void 0;
529
- const actualPermalink = isLabelAsThirdArg ? void 0 : permalink;
530
- const effectiveLabel = isLabelAsThirdArg ? permalink : label || "anonymous_action_state";
531
- const [state, reactDispatch, isPending] = React.useActionState(
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 () => unregisterVariable(effectiveLabel);
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 animationFrame;
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, 60);
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
- renderEmptyState(ctx);
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 () => cancelAnimationFrame(animationFrame);
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.jsxs)("div", { style: { padding: "10px 14px 15px 14px" }, children: [
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
- entries.forEach(([label, vector], rowIndex) => {
648
- const y = rowIndex * HUD_DIMENSIONS.ROW_HEIGHT + HUD_DIMENSIONS.PADDING;
649
- const stateName = label.split(" -> ")[1] || label;
650
- const density = vector.reduce((acc, bit) => acc + bit, 0);
651
- const isVolatile = density > 25;
652
- const isRedundant = redundantLabels.has(label);
653
- vector.forEach((bit, colIndex) => {
654
- const x = colIndex * HUD_DIMENSIONS.COL_WIDTH + HUD_DIMENSIONS.PADDING;
655
- ctx.fillStyle = bit === 1 ? isRedundant ? HUD_THEME.error : HUD_THEME.success : HUD_THEME.grid;
656
- const w = HUD_DIMENSIONS.COL_WIDTH - 1.5;
657
- const h = HUD_DIMENSIONS.ROW_HEIGHT - 4;
658
- if (ctx.roundRect) {
659
- ctx.beginPath();
660
- ctx.roundRect(x, y, w, h, HUD_DIMENSIONS.RADIUS);
661
- ctx.fill();
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
- ctx.fillRect(x, y, w, h);
791
+ gridPath.rect(x, y, cellW, cellH);
664
792
  }
665
- });
666
- const textX = HUD_DIMENSIONS.WINDOW_SIZE * HUD_DIMENSIONS.COL_WIDTH + HUD_DIMENSIONS.PADDING + 10;
667
- ctx.fillStyle = isRedundant ? HUD_THEME.error : isVolatile ? HUD_THEME.success : HUD_THEME.text;
668
- ctx.font = `${isRedundant || isVolatile ? "600" : "400"} 11px Inter, Menlo, monospace`;
669
- let prefix = "";
670
- if (isRedundant) prefix = "! ";
671
- else if (isVolatile) prefix = "~ ";
672
- const cleanName = prefix + stateName;
673
- const truncatedName = cleanName.length > 18 ? cleanName.substring(0, 16) + ".." : cleanName;
674
- ctx.fillText(truncatedName, textX, y + 9);
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)("div", { style: {
678
- padding: "10px 14px",
679
- backgroundColor: isExpanded ? HUD_THEME.header : "transparent",
680
- color: isExpanded ? "white" : HUD_THEME.header,
681
- fontWeight: 600,
682
- fontSize: "11px",
683
- letterSpacing: "0.05em",
684
- display: "flex",
685
- justifyContent: "space-between",
686
- alignItems: "center",
687
- transition: "background 0.3s"
688
- }, children: [
689
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: isExpanded ? "STATE BASIS MATRIX" : "\u{1F4D0} BASIS ACTIVE" }),
690
- isExpanded && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { opacity: 0.8, fontSize: "9px" }, children: "R50" })
691
- ] });
692
- var HUDFooter = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
693
- marginTop: "12px",
694
- paddingTop: "8px",
695
- borderTop: `1px solid ${HUD_THEME.grid}`,
696
- color: HUD_THEME.textDim,
697
- fontSize: "9px",
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,