plug-code 1.2.0 → 2.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.
Files changed (49) hide show
  1. package/README.md +135 -94
  2. package/dist/core/helpers/core.d.ts +2 -0
  3. package/dist/core/helpers/core.js +32 -0
  4. package/dist/core/hooks/plcHooks.d.ts +15 -0
  5. package/dist/core/hooks/plcHooks.js +47 -0
  6. package/dist/core/plcAPI.d.ts +83 -0
  7. package/dist/core/plcAPI.js +472 -0
  8. package/dist/core/plcPipeline.d.ts +8 -0
  9. package/dist/core/plcPipeline.js +35 -0
  10. package/dist/core/plcScheduler.d.ts +7 -0
  11. package/dist/core/plcScheduler.js +22 -0
  12. package/dist/core/plcStore.d.ts +33 -0
  13. package/dist/core/plcStore.js +159 -0
  14. package/dist/core/ui/plcCore.d.ts +8 -0
  15. package/dist/core/ui/plcCore.js +40 -0
  16. package/dist/core/ui/plcErrorBoundary.d.ts +17 -0
  17. package/dist/core/ui/plcErrorBoundary.js +17 -0
  18. package/dist/core/ui/plcInspector.d.ts +5 -0
  19. package/dist/core/ui/plcInspector.js +27 -0
  20. package/dist/core/ui/plcLayout.d.ts +28 -0
  21. package/dist/core/ui/plcLayout.js +125 -0
  22. package/dist/index.d.ts +8 -0
  23. package/dist/index.js +8 -0
  24. package/dist/types/core/api.d.ts +7 -0
  25. package/dist/types/core/api.js +1 -0
  26. package/dist/types/core/general.d.ts +15 -0
  27. package/dist/types/core/general.js +1 -0
  28. package/dist/types/core/registry.d.ts +7 -0
  29. package/dist/types/core/registry.js +1 -0
  30. package/dist/types/core/ui.d.ts +7 -0
  31. package/dist/types/core/ui.js +1 -0
  32. package/dist/types/registry.d.ts +20 -0
  33. package/dist/types/registry.js +1 -0
  34. package/package.json +16 -22
  35. package/index.d.ts +0 -1
  36. package/src/contexts/pipeline.tsx +0 -4
  37. package/src/core/plcAPI.tsx +0 -393
  38. package/src/core/plcPipeline.tsx +0 -87
  39. package/src/core/plcStore.tsx +0 -94
  40. package/src/helpers/core.ts +0 -10
  41. package/src/plug-code.tsx +0 -64
  42. package/src/types/api.ts +0 -8
  43. package/src/types/features.ts +0 -7
  44. package/src/types/general.ts +0 -2
  45. package/src/types/pipeline.ts +0 -3
  46. package/src/types/registry.ts +0 -4
  47. package/src/types/store.ts +0 -2
  48. package/tsconfig.json +0 -15
  49. package/types/plug-code.d.ts +0 -164
@@ -0,0 +1,159 @@
1
+ import { produce } from "immer";
2
+ import { isEqual } from "./helpers/core";
3
+ export class PlcStore {
4
+ storeData = new Map();
5
+ substoresData = new Map();
6
+ subscriptions = new Map();
7
+ isBatching = false;
8
+ dirtyKeys = new Set();
9
+ activeDependencyTracker = null;
10
+ // ----------------------
11
+ // Root store
12
+ // ----------------------
13
+ createStore(key, initial) {
14
+ if (this.storeData.has(key))
15
+ return;
16
+ this.storeData.set(key, initial);
17
+ this.markDirty(key);
18
+ }
19
+ getStore(key) {
20
+ const value = this.storeData.get(key);
21
+ this.recordDependency(key, value);
22
+ return value;
23
+ }
24
+ setStore(key, updater) {
25
+ const prev = this.storeData.get(key);
26
+ const next = typeof updater === 'function'
27
+ ? produce(prev, updater)
28
+ : updater;
29
+ if (isEqual(prev, next))
30
+ return;
31
+ this.storeData.set(key, next);
32
+ this.markDirty(key);
33
+ }
34
+ // ----------------------
35
+ // Substores
36
+ // ----------------------
37
+ createSubstore(substore, key, initial) {
38
+ if (!this.substoresData.has(substore))
39
+ this.substoresData.set(substore, new Map());
40
+ const fStore = this.substoresData.get(substore);
41
+ if (fStore.has(key))
42
+ return;
43
+ fStore.set(key, initial);
44
+ this.markDirty(`${substore}:${key}`);
45
+ }
46
+ getSubstore(substore, key) {
47
+ const fStore = this.substoresData.get(substore);
48
+ const value = fStore?.get(key);
49
+ this.recordDependency(`${substore}:${key}`, value);
50
+ return value;
51
+ }
52
+ setSubstore(substore, key, updater) {
53
+ if (!this.substoresData.has(substore))
54
+ this.substoresData.set(substore, new Map());
55
+ const fStore = this.substoresData.get(substore);
56
+ const prev = fStore.get(key);
57
+ const next = typeof updater === 'function'
58
+ ? produce(prev, updater)
59
+ : updater;
60
+ if (isEqual(prev, next))
61
+ return;
62
+ fStore.set(key, next);
63
+ this.markDirty(`${substore}:${key}`);
64
+ }
65
+ // ----------------------
66
+ // Dependency tracking
67
+ // ----------------------
68
+ recordDependency(key, value) {
69
+ if (this.activeDependencyTracker)
70
+ this.activeDependencyTracker.set(key, value);
71
+ }
72
+ async runWithDependencyTracker(tracker, fn) {
73
+ const prev = this.activeDependencyTracker;
74
+ this.activeDependencyTracker = tracker;
75
+ try {
76
+ return await fn();
77
+ }
78
+ finally {
79
+ this.activeDependencyTracker = prev;
80
+ }
81
+ }
82
+ // ----------------------
83
+ // Subscriptions & batching
84
+ // ----------------------
85
+ batch(fn) {
86
+ const prev = this.isBatching;
87
+ this.isBatching = true;
88
+ try {
89
+ fn();
90
+ }
91
+ finally {
92
+ this.isBatching = prev;
93
+ this.flush();
94
+ }
95
+ }
96
+ subscribe(key, listener) {
97
+ if (!this.subscriptions.has(key))
98
+ this.subscriptions.set(key, new Set());
99
+ this.subscriptions.get(key).add(listener);
100
+ return () => this.subscriptions.get(key).delete(listener);
101
+ }
102
+ markDirty(key) {
103
+ if (this.isBatching)
104
+ this.dirtyKeys.add(key);
105
+ else
106
+ this.notify(key);
107
+ }
108
+ flush() {
109
+ if (this.isBatching)
110
+ return;
111
+ for (const key of this.dirtyKeys)
112
+ this.notify(key);
113
+ this.dirtyKeys.clear();
114
+ }
115
+ notify(key) {
116
+ const listeners = this.subscriptions.get(key);
117
+ listeners?.forEach(fn => {
118
+ try {
119
+ fn();
120
+ }
121
+ catch (err) {
122
+ console.error('[PlcStore] listener threw', err);
123
+ }
124
+ });
125
+ }
126
+ }
127
+ // ----------------------
128
+ // LRUCache
129
+ // ----------------------
130
+ export class LRUCache {
131
+ maxEntries;
132
+ map = new Map();
133
+ constructor(maxEntries = 100) {
134
+ this.maxEntries = maxEntries;
135
+ }
136
+ get(key) {
137
+ if (!this.map.has(key))
138
+ return undefined;
139
+ const val = this.map.get(key);
140
+ this.map.delete(key);
141
+ this.map.set(key, val);
142
+ return val;
143
+ }
144
+ set(key, value) {
145
+ if (this.map.has(key))
146
+ this.map.delete(key);
147
+ else if (this.map.size >= this.maxEntries) {
148
+ const oldest = this.map.keys().next().value;
149
+ this.map.delete(oldest);
150
+ }
151
+ this.map.set(key, value);
152
+ }
153
+ delete(key) {
154
+ this.map.delete(key);
155
+ }
156
+ clear() {
157
+ this.map.clear();
158
+ }
159
+ }
@@ -0,0 +1,8 @@
1
+ import { JSX } from "react";
2
+ type virtualContainerType = {
3
+ content: JSX.Element[];
4
+ config: any;
5
+ contextData: any;
6
+ };
7
+ export declare function VirtualContainer({ content, config, contextData }: virtualContainerType): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { ScopeContext } from "./plcLayout";
4
+ export function VirtualContainer({ content, config, contextData }) {
5
+ const ref = React.useRef(null);
6
+ const rowRefs = React.useRef([]);
7
+ const pipeline = React.useContext(ScopeContext)?.pipeline;
8
+ React.useLayoutEffect(() => {
9
+ if (!ref.current)
10
+ return;
11
+ config.viewport = ref.current.clientHeight;
12
+ }, []);
13
+ const rowHeight = config.itemHeight ?? config.estimatedHeight;
14
+ const total = content.length;
15
+ const start = Math.max(0, Math.floor(config.scrollTop / rowHeight) - config.overscan);
16
+ const end = Math.min(total, Math.ceil((config.scrollTop + config.viewport) / rowHeight) + config.overscan);
17
+ rowRefs.current = [];
18
+ const visible = content.slice(start, end);
19
+ React.useLayoutEffect(() => {
20
+ if (!config.needsMeasure || rowRefs.current.length === 0)
21
+ return;
22
+ const avg = rowRefs.current.reduce((s, el) => s + el.offsetHeight, 0) /
23
+ rowRefs.current.length;
24
+ config.estimatedHeight = avg;
25
+ config.measured = true;
26
+ config.needsMeasure = false;
27
+ pipeline?.scheduleJob(() => { }, 100);
28
+ }, [visible]);
29
+ return (_jsx("div", { ref: ref, onScroll: e => {
30
+ const top = e.currentTarget.scrollTop;
31
+ config.scrollTop = top;
32
+ pipeline?.scheduleJob(() => { }, 100);
33
+ }, style: { overflow: "auto", height: "100%" }, children: _jsx("div", { style: { height: total * rowHeight }, children: _jsx("div", { style: { transform: `translateY(${start * rowHeight}px)` }, children: contextData ? (_jsx(ScopeContext.Provider, { value: contextData, children: visible.map((node, i) => (_jsx("div", { ref: el => {
34
+ if (el)
35
+ rowRefs.current.push(el);
36
+ }, children: node }, i))) })) : (visible.map((node, i) => (_jsx("div", { ref: el => {
37
+ if (el)
38
+ rowRefs.current.push(el);
39
+ }, children: node }, i)))) }) }) }));
40
+ }
@@ -0,0 +1,17 @@
1
+ import { Component, ErrorInfo } from "react";
2
+ export declare class SlotErrorBoundary extends Component<{
3
+ id: string;
4
+ fallback?: React.ReactNode;
5
+ children: React.ReactNode;
6
+ }, {
7
+ hasError: boolean;
8
+ }> {
9
+ state: {
10
+ hasError: boolean;
11
+ };
12
+ static getDerivedStateFromError(_: Error): {
13
+ hasError: boolean;
14
+ };
15
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
16
+ render(): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
17
+ }
@@ -0,0 +1,17 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Component } from "react";
3
+ export class SlotErrorBoundary extends Component {
4
+ state = { hasError: false };
5
+ static getDerivedStateFromError(_) {
6
+ return { hasError: true };
7
+ }
8
+ componentDidCatch(error, errorInfo) {
9
+ console.error(`[PlcLayout] Error in slot item '${this.props.id}':`, error, errorInfo);
10
+ }
11
+ render() {
12
+ if (this.state.hasError) {
13
+ return this.props.fallback || (_jsxs("div", { style: { padding: 4, color: 'red', fontSize: '0.8em', border: '1px dashed red' }, children: ["Error: ", this.props.id] }));
14
+ }
15
+ return this.props.children;
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import { PlcAPI } from "../plcAPI";
3
+ export declare const PlcInspector: React.FC<{
4
+ api: PlcAPI;
5
+ }>;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ const styles = {
4
+ container: { position: 'fixed', bottom: 0, right: 0, width: '300px', height: '400px', background: '#222', color: '#fff', overflow: 'auto', zIndex: 9999, padding: '10px', borderTopLeftRadius: '8px', fontSize: '12px', fontFamily: 'monospace', boxShadow: '-2px -2px 10px rgba(0,0,0,0.5)' },
5
+ header: { borderBottom: '1px solid #444', paddingBottom: '5px', marginBottom: '5px', fontWeight: 'bold', display: 'flex', justifyContent: 'space-between' },
6
+ section: { marginBottom: '10px' },
7
+ label: { color: '#888', marginBottom: '2px' },
8
+ item: { paddingLeft: '10px', color: '#4CAF50' },
9
+ value: { color: '#ce9178' }
10
+ };
11
+ export const PlcInspector = ({ api }) => {
12
+ const [, setTick] = useState(0);
13
+ const [isOpen, setIsOpen] = useState(false);
14
+ useEffect(() => {
15
+ if (!isOpen)
16
+ return;
17
+ const interval = setInterval(() => setTick(t => t + 1), 1000);
18
+ return () => clearInterval(interval);
19
+ }, [isOpen]);
20
+ if (!isOpen) {
21
+ return (_jsx("button", { onClick: () => setIsOpen(true), style: { position: 'fixed', bottom: 10, right: 10, zIndex: 9999, background: '#333', color: '#fff', border: 'none', padding: '5px 10px', borderRadius: '4px', cursor: 'pointer' }, children: "\uD83D\uDEE0\uFE0F PLC" }));
22
+ }
23
+ const slotsMap = api.layout.slots;
24
+ const slots = Array.from(slotsMap.entries());
25
+ const storeKeys = Array.from(api.store.storeData.keys());
26
+ return (_jsxs("div", { style: styles.container, children: [_jsxs("div", { style: styles.header, children: [_jsx("span", { children: "PLC Framework Debugger" }), _jsx("button", { onClick: () => setIsOpen(false), style: { background: 'none', border: 'none', color: '#fff', cursor: 'pointer' }, children: "\u2715" })] }), _jsxs("div", { style: styles.section, children: [_jsxs("div", { style: styles.label, children: ["ACTIVE SLOTS (", slots.length, ")"] }), slots.map(([name, items]) => (_jsxs("div", { children: [_jsx("span", { style: { color: '#569CD6' }, children: name }), _jsxs("span", { style: { color: '#888' }, children: [" (", items.length, ")"] }), items.map((it) => (_jsxs("div", { style: styles.item, children: ["\u2514 ", it.id, " ", _jsxs("span", { style: { fontSize: '0.9em', color: '#888' }, children: ["(prio: ", it.priority, ")"] })] }, it.id)))] }, name)))] }), _jsxs("div", { style: styles.section, children: [_jsx("div", { style: styles.label, children: "ROOT STORE KEYS" }), storeKeys.map((k) => (_jsxs("div", { style: styles.item, children: ["\u2022 ", k] }, k)))] })] }));
27
+ };
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { SlotWrapper } from "../../types/core/ui";
3
+ export declare const ScopeContext: React.Context<any>;
4
+ export type SlotItem = {
5
+ id: string;
6
+ priority: number;
7
+ keepAlive: boolean;
8
+ fn: (props?: any) => React.ReactNode;
9
+ };
10
+ export declare class PlcLayout {
11
+ private slots;
12
+ private virtualRegistry;
13
+ private wrappers;
14
+ private renderCache;
15
+ private cacheVersion;
16
+ markVirtual(slot: string, config?: {
17
+ itemHeight?: number;
18
+ overscan?: number;
19
+ }): void;
20
+ wrap(slot: string, wrapper: SlotWrapper, priority?: number): void;
21
+ register(slot: string, id: string, fn: (props?: any) => React.ReactNode, priority?: number, keepAlive?: boolean): void;
22
+ unregister(slot: string, id: string): void;
23
+ invalidate(slot?: string): void;
24
+ render(slot: string, props?: any): React.ReactNode;
25
+ private renderBase;
26
+ getSlotItems(slot: string): SlotItem[];
27
+ getPriority(slot: string, id: string): number | undefined;
28
+ }
@@ -0,0 +1,125 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, Component } from "react";
3
+ import { VirtualContainer } from "./plcCore";
4
+ export const ScopeContext = createContext(undefined);
5
+ // ---------------------------------------------------------
6
+ // Error Boundary
7
+ // ---------------------------------------------------------
8
+ class SlotErrorBoundary extends Component {
9
+ state = { hasError: false };
10
+ static getDerivedStateFromError(_) {
11
+ return { hasError: true };
12
+ }
13
+ componentDidCatch(error, errorInfo) {
14
+ console.error(`[PlcLayout] Error in slot item '${this.props.id}':`, error, errorInfo);
15
+ }
16
+ render() {
17
+ if (this.state.hasError) {
18
+ return this.props.fallback || (_jsxs("div", { style: { padding: 4, color: 'red', fontSize: '0.8em', border: '1px dashed red' }, children: ["Error: ", this.props.id] }));
19
+ }
20
+ return this.props.children;
21
+ }
22
+ }
23
+ export class PlcLayout {
24
+ slots = new Map();
25
+ virtualRegistry = new Map();
26
+ wrappers = new Map();
27
+ renderCache = new Map();
28
+ cacheVersion = new Map();
29
+ // ---------------------------------------------------------
30
+ // Virtualization
31
+ // ---------------------------------------------------------
32
+ markVirtual(slot, config) {
33
+ this.virtualRegistry.set(slot, {
34
+ itemHeight: config?.itemHeight ?? 32,
35
+ overscan: config?.overscan ?? 6,
36
+ measured: !!config?.itemHeight,
37
+ estimatedHeight: config?.itemHeight ?? 32,
38
+ });
39
+ }
40
+ // ---------------------------------------------------------
41
+ // Middleware (WRAP)
42
+ // ---------------------------------------------------------
43
+ wrap(slot, wrapper, priority = 0) {
44
+ if (!this.wrappers.has(slot)) {
45
+ this.wrappers.set(slot, []);
46
+ }
47
+ this.wrappers.get(slot).push(wrapper);
48
+ this.invalidate(slot);
49
+ }
50
+ // ---------------------------------------------------------
51
+ // Slot Manager
52
+ // ---------------------------------------------------------
53
+ register(slot, id, fn, priority = 0, keepAlive = false) {
54
+ if (!this.slots.has(slot)) {
55
+ this.slots.set(slot, []);
56
+ this.cacheVersion.set(slot, 0);
57
+ }
58
+ const list = this.slots.get(slot);
59
+ const existingIdx = list.findIndex(x => x.id === id);
60
+ const item = { id, priority, fn, keepAlive };
61
+ if (existingIdx >= 0)
62
+ list[existingIdx] = item;
63
+ else
64
+ list.push(item);
65
+ list.sort((a, b) => b.priority - a.priority);
66
+ this.invalidate(slot);
67
+ }
68
+ unregister(slot, id) {
69
+ const list = this.slots.get(slot);
70
+ if (!list)
71
+ return;
72
+ const idx = list.findIndex(x => x.id === id);
73
+ if (idx >= 0) {
74
+ list.splice(idx, 1);
75
+ this.invalidate(slot);
76
+ }
77
+ }
78
+ // ---------------------------------------------------------
79
+ // Render
80
+ // ---------------------------------------------------------
81
+ invalidate(slot) {
82
+ if (slot) {
83
+ this.renderCache.delete(slot);
84
+ this.cacheVersion.set(slot, (this.cacheVersion.get(slot) || 0) + 1);
85
+ }
86
+ else {
87
+ this.renderCache.clear();
88
+ for (const k of this.cacheVersion.keys()) {
89
+ this.cacheVersion.set(k, (this.cacheVersion.get(k) || 0) + 1);
90
+ }
91
+ }
92
+ }
93
+ render(slot, props) {
94
+ let content = this.renderBase(slot, props);
95
+ const slotWrappers = this.wrappers.get(slot);
96
+ if (slotWrappers && slotWrappers.length > 0) {
97
+ for (const wrapFn of slotWrappers) {
98
+ content = wrapFn(content, props);
99
+ }
100
+ }
101
+ return content;
102
+ }
103
+ renderBase(slot, props) {
104
+ const list = this.slots.get(slot) || [];
105
+ const virtualConfig = this.virtualRegistry.get(slot);
106
+ if (virtualConfig && list.length > 0) {
107
+ const protectedItems = list.map(item => ({
108
+ ...item,
109
+ fn: (p) => (_jsx(SlotErrorBoundary, { id: item.id, children: item.fn(p) }))
110
+ }));
111
+ const content = protectedItems.map((item, i) => (_jsx(ScopeContext.Provider, { value: props, children: item.fn(props) }, item.id)));
112
+ return (_jsx(VirtualContainer, { content: content, config: virtualConfig, contextData: props }));
113
+ }
114
+ return list.map(item => {
115
+ const isActive = props?.activeId ? props.activeId === item.id : true;
116
+ if (!isActive && !item.keepAlive)
117
+ return null;
118
+ return (_jsx("div", { style: { display: isActive ? undefined : 'none' }, children: _jsx(SlotErrorBoundary, { id: item.id, children: _jsx(ScopeContext.Provider, { value: props, children: item.fn(props) }) }) }, item.id));
119
+ });
120
+ }
121
+ getSlotItems(slot) { return this.slots.get(slot) || []; }
122
+ getPriority(slot, id) {
123
+ return this.slots.get(slot)?.find(x => x.id === id)?.priority;
124
+ }
125
+ }
@@ -0,0 +1,8 @@
1
+ export * from "./core/plcAPI";
2
+ export * from "./core/plcStore";
3
+ export * from "./core/plcPipeline";
4
+ export * from "./core/plcScheduler";
5
+ export * from "./core/helpers/core";
6
+ export * from "./types/core/general";
7
+ export * from "./types/core/api";
8
+ export * from "./types/core/registry";
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./core/plcAPI";
2
+ export * from "./core/plcStore";
3
+ export * from "./core/plcPipeline";
4
+ export * from "./core/plcScheduler";
5
+ export * from "./core/helpers/core";
6
+ export * from "./types/core/general";
7
+ export * from "./types/core/api";
8
+ export * from "./types/core/registry";
@@ -0,0 +1,7 @@
1
+ export type CommandFn<Payload = any, Result = any> = (payload?: Payload) => Promise<Result> | Result;
2
+ export type CommandWrapper<P = any, R = any> = (next: CommandFn<P, R>) => CommandFn<P, R>;
3
+ export type transformerType<T = any> = {
4
+ id: string;
5
+ priority: number;
6
+ fn: (data: T, context: any) => T;
7
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { PlcAPI } from "../../core/plcAPI";
2
+ import { CommandFn } from "./api";
3
+ export type ObjectType = Record<string, any>;
4
+ export type ModuleManifest = {
5
+ name: string;
6
+ state?: Record<string, any>;
7
+ commands?: Record<string, CommandFn>;
8
+ slots?: Record<string, {
9
+ id: string;
10
+ component: (props?: any) => React.ReactNode;
11
+ priority?: number;
12
+ keepAlive?: boolean;
13
+ }[]>;
14
+ onLoad?: (api: PlcAPI) => void;
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { ObjectType } from "./general";
2
+ export type SlotRegistry = ObjectType;
3
+ export type ChannelRegistry = ObjectType;
4
+ export type CommandRegistry = Record<string, {
5
+ payload?: any;
6
+ result?: any;
7
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export type SlotWrapper = (next: React.ReactNode, props?: any) => React.ReactNode;
2
+ export type VirtualConfig = {
3
+ itemHeight: number;
4
+ overscan: number;
5
+ measured: boolean;
6
+ estimatedHeight: number;
7
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ export interface RootStoreRegistry {
2
+ }
3
+ export interface CommandRegistry {
4
+ }
5
+ export interface SlotRegistry {
6
+ }
7
+ export interface FeatureRegistry {
8
+ }
9
+ export type StoreKey = keyof RootStoreRegistry extends never ? string : keyof RootStoreRegistry;
10
+ export type StoreValue<K extends StoreKey> = K extends keyof RootStoreRegistry ? RootStoreRegistry[K] : any;
11
+ export type CommandKey = keyof CommandRegistry extends never ? string : keyof CommandRegistry;
12
+ export type SlotKey = keyof SlotRegistry extends never ? string : keyof SlotRegistry;
13
+ export type FeatureKey = keyof FeatureRegistry extends never ? string : keyof FeatureRegistry;
14
+ export type CmdPayload<K extends CommandKey> = K extends keyof CommandRegistry ? (CommandRegistry[K] extends {
15
+ payload: infer P;
16
+ } ? P : void) : any;
17
+ export type CmdResult<K extends CommandKey> = K extends keyof CommandRegistry ? (CommandRegistry[K] extends {
18
+ result: infer R;
19
+ } ? R : void) : any;
20
+ export type SlotProps<K extends SlotKey> = K extends keyof SlotRegistry ? SlotRegistry[K] : any;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,37 +1,31 @@
1
1
  {
2
2
  "name": "plug-code",
3
- "version": "1.2.0",
3
+ "version": "2.0.1",
4
4
  "description": "",
5
- "main": "src/plug-code.tsx",
6
- "types": "types/plug-code.d.ts",
7
- "exports": {
8
- ".": {
9
- "import": "./src/plug-code.tsx",
10
- "require": "./src/plug-code.tsx"
11
- }
12
- },
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
13
10
  "scripts": {
14
- "test": "echo \"Error: no test specified\" && exit 1",
15
- "build:types": "tsc -p tsconfig.json"
16
- },
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/AlaunS/plug-code.git"
11
+ "build": "tsc",
12
+ "watch": "tsc --watch",
13
+ "test": "jest"
20
14
  },
21
15
  "keywords": [],
22
16
  "author": "",
23
17
  "license": "ISC",
24
18
  "type": "commonjs",
25
- "bugs": {
26
- "url": "https://github.com/AlaunS/plug-code/issues"
19
+ "devDependencies": {
20
+ "@types/jest": "^30.0.0",
21
+ "@types/node": "^25.0.3",
22
+ "@types/react": "^19.2.7",
23
+ "jest": "^30.2.0",
24
+ "ts-jest": "^29.4.6",
25
+ "typescript": "^5.9.3"
27
26
  },
28
- "homepage": "https://github.com/AlaunS/plug-code#readme",
29
27
  "dependencies": {
30
28
  "immer": "^11.1.3",
31
29
  "react": "^19.2.3"
32
- },
33
- "devDependencies": {
34
- "@types/react": "^19.2.7",
35
- "typescript": "^5.4.2"
36
30
  }
37
31
  }
package/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./types/plug-code";
@@ -1,4 +0,0 @@
1
- import { createContext, useContext } from "react";
2
-
3
- export const ScopeContext = createContext<any>(null);
4
- export const useScopeData = <T,>() => useContext(ScopeContext) as T;