@logixjs/devtools-react 0.0.1

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.
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import * as Logix from '@logixjs/core';
3
+
4
+ interface LogixDevtoolsProps {
5
+ readonly position?: 'bottom-left' | 'bottom-right';
6
+ readonly initialOpen?: boolean;
7
+ /**
8
+ * Optional: provide a StateTraitProgram for the currently selected moduleId,
9
+ * so Devtools can render StateTraitGraph in the Inspector panel and coordinate with the Timeline.
10
+ * - If not provided, the Graph section only shows a placeholder and does not affect Timeline / Inspector behavior.
11
+ */
12
+ readonly getProgramForModule?: (moduleId: string) => Logix.StateTrait.StateTraitProgram<any> | undefined;
13
+ }
14
+ declare const LogixDevtools: React.FC<LogixDevtoolsProps>;
15
+
16
+ export { LogixDevtools };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import * as Logix from '@logixjs/core';
3
+
4
+ interface LogixDevtoolsProps {
5
+ readonly position?: 'bottom-left' | 'bottom-right';
6
+ readonly initialOpen?: boolean;
7
+ /**
8
+ * Optional: provide a StateTraitProgram for the currently selected moduleId,
9
+ * so Devtools can render StateTraitGraph in the Inspector panel and coordinate with the Timeline.
10
+ * - If not provided, the Graph section only shows a placeholder and does not affect Timeline / Inspector behavior.
11
+ */
12
+ readonly getProgramForModule?: (moduleId: string) => Logix.StateTrait.StateTraitProgram<any> | undefined;
13
+ }
14
+ declare const LogixDevtools: React.FC<LogixDevtoolsProps>;
15
+
16
+ export { LogixDevtools };
@@ -0,0 +1,8 @@
1
+ import {
2
+ LogixDevtools
3
+ } from "./chunk-WTZBDE4J.js";
4
+ import "./chunk-FNWHBEXD.js";
5
+ import "./chunk-CZWYV2AZ.js";
6
+ export {
7
+ LogixDevtools
8
+ };
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/StateTraitGraphView.tsx
21
+ var StateTraitGraphView_exports = {};
22
+ __export(StateTraitGraphView_exports, {
23
+ StateTraitGraphView: () => StateTraitGraphView
24
+ });
25
+ module.exports = __toCommonJS(StateTraitGraphView_exports);
26
+
27
+ // src/style.ts
28
+ var import_meta = {};
29
+ var styleMarkerAttribute = "data-logix-devtools-style";
30
+ var ensureDevtoolsStyles = () => {
31
+ if (typeof document === "undefined") return;
32
+ const existing = document.querySelector(`link[${styleMarkerAttribute}="true"]`);
33
+ if (existing) return;
34
+ let href;
35
+ try {
36
+ href = new URL("./style.css", import_meta.url).toString();
37
+ } catch {
38
+ return;
39
+ }
40
+ const link = document.createElement("link");
41
+ link.rel = "stylesheet";
42
+ link.href = href;
43
+ link.setAttribute(styleMarkerAttribute, "true");
44
+ document.head.appendChild(link);
45
+ };
46
+
47
+ // src/internal/ui/graph/StateTraitGraphView.tsx
48
+ var import_jsx_runtime = require("react/jsx-runtime");
49
+ var StateTraitGraphView = ({
50
+ program,
51
+ onSelectNode,
52
+ selectedFieldPath
53
+ }) => {
54
+ if (!program) {
55
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
56
+ "div",
57
+ {
58
+ className: "text-xs px-3 py-2",
59
+ style: {
60
+ color: "var(--dt-text-muted)",
61
+ backgroundColor: "var(--dt-bg-surface)"
62
+ },
63
+ children: "No StateTraitProgram available for this module."
64
+ }
65
+ );
66
+ }
67
+ const { graph } = program;
68
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
69
+ "div",
70
+ {
71
+ className: "text-[10px] font-mono px-3 py-2 space-y-2 overflow-auto",
72
+ style: {
73
+ backgroundColor: "var(--dt-bg-surface)",
74
+ color: "var(--dt-text-primary)"
75
+ },
76
+ children: [
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-[9px] uppercase tracking-wide mb-1", style: { color: "var(--dt-text-muted)" }, children: "StateTraitGraph" }),
78
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
79
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-[9px] mb-1", style: { color: "var(--dt-text-secondary)" }, children: [
80
+ "Nodes (",
81
+ graph.nodes.length,
82
+ ")"
83
+ ] }),
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "space-y-0.5", children: graph.nodes.map((node) => {
85
+ const fieldPath = node.field.path;
86
+ const label = node.meta?.label;
87
+ const tags = node.meta?.tags ?? [];
88
+ const handleClick = () => {
89
+ if (onSelectNode) {
90
+ onSelectNode(fieldPath);
91
+ }
92
+ };
93
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { className: "flex items-center justify-between gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
94
+ "button",
95
+ {
96
+ type: "button",
97
+ onClick: handleClick,
98
+ className: "flex-1 flex items-center justify-between gap-2 text-left hover:bg-[var(--dt-bg-element)] rounded px-1 py-0.5 transition-colors",
99
+ style: selectedFieldPath === fieldPath ? {
100
+ backgroundColor: "var(--dt-info-bg)",
101
+ boxShadow: "0 0 0 1px var(--dt-info)"
102
+ } : void 0,
103
+ children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex flex-col gap-0.5 min-w-0", children: [
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate", children: label ?? fieldPath }),
106
+ label ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[9px] truncate", style: { color: "var(--dt-text-muted)" }, children: fieldPath }) : null
107
+ ] }),
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-[9px]", style: { color: "var(--dt-text-muted)" }, children: [
109
+ node.traits.map((t) => t.kind).join(", ") || "\u2014",
110
+ tags.length > 0 ? ` \xB7 #${tags.join(" #")}` : ""
111
+ ] })
112
+ ]
113
+ }
114
+ ) }, node.id);
115
+ }) })
116
+ ] }),
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-[9px] mt-2 mb-1", style: { color: "var(--dt-text-secondary)" }, children: [
119
+ "Resources (",
120
+ graph.resources.length,
121
+ ")"
122
+ ] }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "space-y-0.5", children: graph.resources.map((res) => {
124
+ const label = res.meta?.label;
125
+ const tags = res.meta?.tags ?? [];
126
+ const conflicts = res.metaConflicts ?? [];
127
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "flex items-center justify-between gap-2", children: [
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
129
+ res.resourceId,
130
+ label ? ` \xB7 ${label}` : ""
131
+ ] }),
132
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-[9px] flex items-center gap-2", style: { color: "var(--dt-text-muted)" }, children: [
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
134
+ "owners: ",
135
+ res.ownerFields.length
136
+ ] }),
137
+ tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
138
+ "#",
139
+ tags.join(" #")
140
+ ] }) : null,
141
+ conflicts.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
142
+ "span",
143
+ {
144
+ className: "px-1 rounded",
145
+ style: {
146
+ color: "var(--dt-danger)",
147
+ backgroundColor: "var(--dt-danger-bg)",
148
+ boxShadow: "0 0 0 1px var(--dt-danger-border)"
149
+ },
150
+ title: "Multiple conflicting meta declarations detected for this resource id.",
151
+ children: [
152
+ "meta-conflict+",
153
+ conflicts.length
154
+ ]
155
+ }
156
+ ) : null
157
+ ] })
158
+ ] }, res.resourceId);
159
+ }) })
160
+ ] }),
161
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-[9px] mt-2 mb-1", style: { color: "var(--dt-text-secondary)" }, children: [
163
+ "Edges (",
164
+ graph.edges.length,
165
+ ")"
166
+ ] }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "space-y-0.5", children: graph.edges.map((edge) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: "flex items-center justify-between gap-2", children: [
168
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
169
+ edge.from,
170
+ " \u2192 ",
171
+ edge.to
172
+ ] }),
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[9px]", style: { color: "var(--dt-text-muted)" }, children: edge.kind })
174
+ ] }, edge.id)) })
175
+ ] })
176
+ ]
177
+ }
178
+ );
179
+ };
180
+
181
+ // src/StateTraitGraphView.tsx
182
+ ensureDevtoolsStyles();
183
+ // Annotate the CommonJS export names for ESM import in node:
184
+ 0 && (module.exports = {
185
+ StateTraitGraphView
186
+ });
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import * as Logix from '@logixjs/core';
3
+
4
+ interface StateTraitGraphViewProps {
5
+ /**
6
+ * Program output from Debug.getModuleTraits(module).
7
+ * - If not provided, the component only renders a placeholder.
8
+ */
9
+ readonly program?: Logix.StateTrait.StateTraitProgram<any>;
10
+ /**
11
+ * Optional: notify the caller when the user clicks a field node,
12
+ * so the caller can coordinate the EffectOp timeline (e.g. filter by fieldPath).
13
+ */
14
+ readonly onSelectNode?: (fieldPath: string) => void;
15
+ /**
16
+ * Optional: the currently selected fieldPath to highlight in the graph.
17
+ */
18
+ readonly selectedFieldPath?: string;
19
+ }
20
+ declare const StateTraitGraphView: React.FC<StateTraitGraphViewProps>;
21
+
22
+ export { StateTraitGraphView };
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import * as Logix from '@logixjs/core';
3
+
4
+ interface StateTraitGraphViewProps {
5
+ /**
6
+ * Program output from Debug.getModuleTraits(module).
7
+ * - If not provided, the component only renders a placeholder.
8
+ */
9
+ readonly program?: Logix.StateTrait.StateTraitProgram<any>;
10
+ /**
11
+ * Optional: notify the caller when the user clicks a field node,
12
+ * so the caller can coordinate the EffectOp timeline (e.g. filter by fieldPath).
13
+ */
14
+ readonly onSelectNode?: (fieldPath: string) => void;
15
+ /**
16
+ * Optional: the currently selected fieldPath to highlight in the graph.
17
+ */
18
+ readonly selectedFieldPath?: string;
19
+ }
20
+ declare const StateTraitGraphView: React.FC<StateTraitGraphViewProps>;
21
+
22
+ export { StateTraitGraphView };
@@ -0,0 +1,7 @@
1
+ import "./chunk-AELNVFJN.js";
2
+ import {
3
+ StateTraitGraphView
4
+ } from "./chunk-CZWYV2AZ.js";
5
+ export {
6
+ StateTraitGraphView
7
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ ensureDevtoolsStyles
3
+ } from "./chunk-CZWYV2AZ.js";
4
+
5
+ // src/StateTraitGraphView.tsx
6
+ ensureDevtoolsStyles();
@@ -0,0 +1,157 @@
1
+ // src/style.ts
2
+ var styleMarkerAttribute = "data-logix-devtools-style";
3
+ var ensureDevtoolsStyles = () => {
4
+ if (typeof document === "undefined") return;
5
+ const existing = document.querySelector(`link[${styleMarkerAttribute}="true"]`);
6
+ if (existing) return;
7
+ let href;
8
+ try {
9
+ href = new URL("./style.css", import.meta.url).toString();
10
+ } catch {
11
+ return;
12
+ }
13
+ const link = document.createElement("link");
14
+ link.rel = "stylesheet";
15
+ link.href = href;
16
+ link.setAttribute(styleMarkerAttribute, "true");
17
+ document.head.appendChild(link);
18
+ };
19
+
20
+ // src/internal/ui/graph/StateTraitGraphView.tsx
21
+ import { jsx, jsxs } from "react/jsx-runtime";
22
+ var StateTraitGraphView = ({
23
+ program,
24
+ onSelectNode,
25
+ selectedFieldPath
26
+ }) => {
27
+ if (!program) {
28
+ return /* @__PURE__ */ jsx(
29
+ "div",
30
+ {
31
+ className: "text-xs px-3 py-2",
32
+ style: {
33
+ color: "var(--dt-text-muted)",
34
+ backgroundColor: "var(--dt-bg-surface)"
35
+ },
36
+ children: "No StateTraitProgram available for this module."
37
+ }
38
+ );
39
+ }
40
+ const { graph } = program;
41
+ return /* @__PURE__ */ jsxs(
42
+ "div",
43
+ {
44
+ className: "text-[10px] font-mono px-3 py-2 space-y-2 overflow-auto",
45
+ style: {
46
+ backgroundColor: "var(--dt-bg-surface)",
47
+ color: "var(--dt-text-primary)"
48
+ },
49
+ children: [
50
+ /* @__PURE__ */ jsx("div", { className: "text-[9px] uppercase tracking-wide mb-1", style: { color: "var(--dt-text-muted)" }, children: "StateTraitGraph" }),
51
+ /* @__PURE__ */ jsxs("div", { children: [
52
+ /* @__PURE__ */ jsxs("div", { className: "text-[9px] mb-1", style: { color: "var(--dt-text-secondary)" }, children: [
53
+ "Nodes (",
54
+ graph.nodes.length,
55
+ ")"
56
+ ] }),
57
+ /* @__PURE__ */ jsx("ul", { className: "space-y-0.5", children: graph.nodes.map((node) => {
58
+ const fieldPath = node.field.path;
59
+ const label = node.meta?.label;
60
+ const tags = node.meta?.tags ?? [];
61
+ const handleClick = () => {
62
+ if (onSelectNode) {
63
+ onSelectNode(fieldPath);
64
+ }
65
+ };
66
+ return /* @__PURE__ */ jsx("li", { className: "flex items-center justify-between gap-2", children: /* @__PURE__ */ jsxs(
67
+ "button",
68
+ {
69
+ type: "button",
70
+ onClick: handleClick,
71
+ className: "flex-1 flex items-center justify-between gap-2 text-left hover:bg-[var(--dt-bg-element)] rounded px-1 py-0.5 transition-colors",
72
+ style: selectedFieldPath === fieldPath ? {
73
+ backgroundColor: "var(--dt-info-bg)",
74
+ boxShadow: "0 0 0 1px var(--dt-info)"
75
+ } : void 0,
76
+ children: [
77
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-col gap-0.5 min-w-0", children: [
78
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label ?? fieldPath }),
79
+ label ? /* @__PURE__ */ jsx("span", { className: "text-[9px] truncate", style: { color: "var(--dt-text-muted)" }, children: fieldPath }) : null
80
+ ] }),
81
+ /* @__PURE__ */ jsxs("span", { className: "text-[9px]", style: { color: "var(--dt-text-muted)" }, children: [
82
+ node.traits.map((t) => t.kind).join(", ") || "\u2014",
83
+ tags.length > 0 ? ` \xB7 #${tags.join(" #")}` : ""
84
+ ] })
85
+ ]
86
+ }
87
+ ) }, node.id);
88
+ }) })
89
+ ] }),
90
+ /* @__PURE__ */ jsxs("div", { children: [
91
+ /* @__PURE__ */ jsxs("div", { className: "text-[9px] mt-2 mb-1", style: { color: "var(--dt-text-secondary)" }, children: [
92
+ "Resources (",
93
+ graph.resources.length,
94
+ ")"
95
+ ] }),
96
+ /* @__PURE__ */ jsx("ul", { className: "space-y-0.5", children: graph.resources.map((res) => {
97
+ const label = res.meta?.label;
98
+ const tags = res.meta?.tags ?? [];
99
+ const conflicts = res.metaConflicts ?? [];
100
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2", children: [
101
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate", children: [
102
+ res.resourceId,
103
+ label ? ` \xB7 ${label}` : ""
104
+ ] }),
105
+ /* @__PURE__ */ jsxs("span", { className: "text-[9px] flex items-center gap-2", style: { color: "var(--dt-text-muted)" }, children: [
106
+ /* @__PURE__ */ jsxs("span", { children: [
107
+ "owners: ",
108
+ res.ownerFields.length
109
+ ] }),
110
+ tags.length > 0 ? /* @__PURE__ */ jsxs("span", { children: [
111
+ "#",
112
+ tags.join(" #")
113
+ ] }) : null,
114
+ conflicts.length > 0 ? /* @__PURE__ */ jsxs(
115
+ "span",
116
+ {
117
+ className: "px-1 rounded",
118
+ style: {
119
+ color: "var(--dt-danger)",
120
+ backgroundColor: "var(--dt-danger-bg)",
121
+ boxShadow: "0 0 0 1px var(--dt-danger-border)"
122
+ },
123
+ title: "Multiple conflicting meta declarations detected for this resource id.",
124
+ children: [
125
+ "meta-conflict+",
126
+ conflicts.length
127
+ ]
128
+ }
129
+ ) : null
130
+ ] })
131
+ ] }, res.resourceId);
132
+ }) })
133
+ ] }),
134
+ /* @__PURE__ */ jsxs("div", { children: [
135
+ /* @__PURE__ */ jsxs("div", { className: "text-[9px] mt-2 mb-1", style: { color: "var(--dt-text-secondary)" }, children: [
136
+ "Edges (",
137
+ graph.edges.length,
138
+ ")"
139
+ ] }),
140
+ /* @__PURE__ */ jsx("ul", { className: "space-y-0.5", children: graph.edges.map((edge) => /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2", children: [
141
+ /* @__PURE__ */ jsxs("span", { children: [
142
+ edge.from,
143
+ " \u2192 ",
144
+ edge.to
145
+ ] }),
146
+ /* @__PURE__ */ jsx("span", { className: "text-[9px]", style: { color: "var(--dt-text-muted)" }, children: edge.kind })
147
+ ] }, edge.id)) })
148
+ ] })
149
+ ]
150
+ }
151
+ );
152
+ };
153
+
154
+ export {
155
+ ensureDevtoolsStyles,
156
+ StateTraitGraphView
157
+ };
@@ -0,0 +1,123 @@
1
+ // src/internal/snapshot/index.ts
2
+ import * as Logix from "@logixjs/core";
3
+ import { Context, Effect, Layer, Stream } from "effect";
4
+ var clearDevtoolsEvents = Logix.Debug.clearDevtoolsEvents;
5
+ var setInstanceLabel = Logix.Debug.setInstanceLabel;
6
+ var getInstanceLabel = Logix.Debug.getInstanceLabel;
7
+ var snapshotOverride;
8
+ var snapshotOverrideInfo;
9
+ var overrideSnapshotToken = Number.MIN_SAFE_INTEGER;
10
+ var nextOverrideSnapshotToken = () => {
11
+ overrideSnapshotToken += 1;
12
+ return overrideSnapshotToken;
13
+ };
14
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
15
+ var asNonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
16
+ var asNonNegativeInt = (value) => {
17
+ if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
18
+ const n = Math.floor(value);
19
+ return n >= 0 ? n : void 0;
20
+ };
21
+ var normalizeTxnSeqFromTxnId = (txnId, instanceId) => {
22
+ if (!txnId) return void 0;
23
+ const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24
+ const m = instanceId ? txnId.match(new RegExp(`^${escapeRe(instanceId)}::t(\\d+)$`)) : txnId.match(/::t(\d+)$/);
25
+ if (!m) return void 0;
26
+ const n = Number(m[1]);
27
+ return Number.isFinite(n) && n >= 0 ? Math.floor(n) : void 0;
28
+ };
29
+ var normalizeDevtoolsSnapshot = (snapshot) => {
30
+ const events = snapshot.events.map((e, index) => {
31
+ if (!isRecord(e)) {
32
+ return e;
33
+ }
34
+ const instanceId = asNonEmptyString(e.instanceId);
35
+ const txnId = asNonEmptyString(e.txnId);
36
+ const txnSeq = asNonNegativeInt(e.txnSeq) ?? normalizeTxnSeqFromTxnId(txnId, instanceId) ?? 0;
37
+ const eventSeq = asNonNegativeInt(e.eventSeq) ?? index + 1;
38
+ const eventId = asNonEmptyString(e.eventId) ?? (instanceId ? `${instanceId}::e${eventSeq}` : `unknown::e${eventSeq}`);
39
+ const patched = { ...e, eventId, eventSeq, txnSeq };
40
+ if (!patched.txnId && instanceId && txnSeq > 0) {
41
+ patched.txnId = `${instanceId}::t${txnSeq}`;
42
+ }
43
+ return patched;
44
+ });
45
+ return { ...snapshot, events };
46
+ };
47
+ var listeners = /* @__PURE__ */ new Set();
48
+ var unsubscribeCore;
49
+ var notify = () => {
50
+ for (const listener of listeners) {
51
+ listener();
52
+ }
53
+ };
54
+ var ensureCoreSubscribed = () => {
55
+ if (unsubscribeCore) return;
56
+ unsubscribeCore = Logix.Debug.subscribeDevtoolsSnapshot(() => {
57
+ if (snapshotOverride) return;
58
+ notify();
59
+ });
60
+ };
61
+ var hasDevtoolsSnapshotOverride = () => snapshotOverride != null;
62
+ var getDevtoolsSnapshotOverrideInfo = () => snapshotOverrideInfo;
63
+ var setDevtoolsSnapshotOverride = (snapshot, info) => {
64
+ snapshotOverride = normalizeDevtoolsSnapshot({
65
+ ...snapshot,
66
+ snapshotToken: nextOverrideSnapshotToken()
67
+ });
68
+ snapshotOverrideInfo = info;
69
+ notify();
70
+ };
71
+ var clearDevtoolsSnapshotOverride = () => {
72
+ snapshotOverride = void 0;
73
+ snapshotOverrideInfo = void 0;
74
+ notify();
75
+ };
76
+ var getDevtoolsSnapshot = () => snapshotOverride ?? Logix.Debug.getDevtoolsSnapshot();
77
+ var getDevtoolsSnapshotToken = () => getDevtoolsSnapshot().snapshotToken;
78
+ var subscribeDevtoolsSnapshot = (listener) => {
79
+ listeners.add(listener);
80
+ ensureCoreSubscribed();
81
+ return () => {
82
+ listeners.delete(listener);
83
+ if (listeners.size === 0 && unsubscribeCore) {
84
+ unsubscribeCore();
85
+ unsubscribeCore = void 0;
86
+ }
87
+ };
88
+ };
89
+ var subscribeDevtoolsSnapshotToken = subscribeDevtoolsSnapshot;
90
+ var devtoolsLayer = Logix.Debug.devtoolsHubLayer();
91
+ var DevtoolsSnapshotStore = class extends Context.Tag("Logix/DevtoolsSnapshotStore")() {
92
+ };
93
+ var devtoolsSnapshotService = {
94
+ get: Effect.sync(() => getDevtoolsSnapshot()),
95
+ changes: Stream.async((emit) => {
96
+ const listener = () => {
97
+ emit.single(getDevtoolsSnapshot());
98
+ };
99
+ const unsubscribe = subscribeDevtoolsSnapshot(listener);
100
+ return Effect.sync(unsubscribe);
101
+ })
102
+ };
103
+ var devtoolsSnapshotLayer = Layer.succeed(
104
+ DevtoolsSnapshotStore,
105
+ devtoolsSnapshotService
106
+ );
107
+
108
+ export {
109
+ clearDevtoolsEvents,
110
+ setInstanceLabel,
111
+ getInstanceLabel,
112
+ hasDevtoolsSnapshotOverride,
113
+ getDevtoolsSnapshotOverrideInfo,
114
+ setDevtoolsSnapshotOverride,
115
+ clearDevtoolsSnapshotOverride,
116
+ getDevtoolsSnapshot,
117
+ getDevtoolsSnapshotToken,
118
+ subscribeDevtoolsSnapshot,
119
+ subscribeDevtoolsSnapshotToken,
120
+ devtoolsLayer,
121
+ DevtoolsSnapshotStore,
122
+ devtoolsSnapshotLayer
123
+ };
File without changes