plug-code 1.0.3 → 1.1.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.
package/README.md CHANGED
@@ -1,16 +1,116 @@
1
1
  # Plug&Code
2
2
 
3
- Plug&Code is a multipurpose framework for React, designed for **scalability, reusability, and organized components**.
3
+ Plug&Code is a multipurpose framework for React designed for **scalability, reusability, and modular organization**. It allows you to build complex applications by "plugging in" features without tightly coupling your codebase.
4
4
 
5
5
  ## Usage
6
6
 
7
- You are welcome to use Plug&Code in your projects, **personal or commercial**, as long as you **do not modify or redistribute the framework** without explicit permission from the author.
7
+ You are welcome to use Plug&Code in your projects, **personal or commercial**, as long as you **do not modify or redistribute the framework** without explicit permission from the author.
8
+
9
+ ---
8
10
 
9
11
  ### Installation
10
12
 
11
- You can install the framework via npm or yarn:
13
+ Install the framework via npm or yarn:
12
14
 
13
15
  ```bash
14
16
  npm install plug-code
15
17
  # or
16
18
  yarn add plug-code
19
+
20
+ ```
21
+
22
+ ### Core Concepts
23
+
24
+ Plug&Code is built around the **PLC (Pipeline-Logic-Command)** pattern:
25
+
26
+ * **Slots (UI Pipeline):** Inject components into pre-defined locations from any feature.
27
+ * **Commands (Logic):** Execute and wrap business actions (e.g., `checkout`, `print`, `save`).
28
+ * **Transforms (Data):** Pass data through named channels to be modified by different features.
29
+
30
+ ---
31
+
32
+ ### Quick Start Guide
33
+
34
+ #### 1. Initialize your System
35
+
36
+ Define your system and register features using the fluent API.
37
+
38
+ ```tsx
39
+ import { createPlugAndCode } from 'plug-code';
40
+
41
+ export const { useSystemPlc, SystemPlcRoot } = createPlugAndCode((api) => {
42
+
43
+ // Define a Sales Feature
44
+ api.feature("sales", (api) => {
45
+ // Register a UI component into a slot
46
+ api.register("header.cart", () => <CartIcon />);
47
+
48
+ // Register a business command
49
+ api.registerCommand("sales.checkout", async (items) => {
50
+ console.log("Saving items to database...", items);
51
+ return { success: true };
52
+ });
53
+ });
54
+
55
+ // Define a Logger Feature that wraps existing logic
56
+ api.feature("logger", (api) => {
57
+ api.wrapCommand("sales.checkout", (next) => async (items) => {
58
+ console.log("Checkout started...");
59
+ const result = await next(items);
60
+ console.log("Checkout finished:", result);
61
+ return result;
62
+ });
63
+ });
64
+ });
65
+
66
+ ```
67
+
68
+ #### 2. Wrap your Application
69
+
70
+ Use the `useSystemPlc` hook to manage the state and `SystemPlcRoot` to provide the context.
71
+
72
+ ```tsx
73
+ function App() {
74
+ // Initialize state with initial properties
75
+ const { api, useSelector } = useSystemPlc({ shopName: "My Store" });
76
+
77
+ return (
78
+ <SystemPlcRoot api={api}>
79
+ <nav>
80
+ {/* Render slots from any feature */}
81
+ {api.render("header.cart")}
82
+ </nav>
83
+ <main>
84
+ <h1>Welcome to {useSelector(s => s.root.shopName)}</h1>
85
+ </main>
86
+ </SystemPlcRoot>
87
+ );
88
+ }
89
+
90
+ ```
91
+
92
+ ---
93
+
94
+ ### API Reference
95
+
96
+ #### **UI Management (Slots)**
97
+
98
+ * `api.register(slotName, component)`: Adds a UI component to a slot.
99
+ * `api.render(slotName)`: Renders all components registered in that slot.
100
+ * `api.wrap(slot, wrapper)`: Wraps a slot's content with higher-order components.
101
+
102
+ #### **Business Logic (Commands)**
103
+
104
+ * `api.registerCommand(id, fn)`: Registers an executable action.
105
+ * `api.execute(id, payload)`: Runs a command and returns a Promise.
106
+ * `api.wrapCommand(id, (next) => ...)`: Intercepts a command to add side-effects or validations.
107
+
108
+ #### **Data Processing (Transforms)**
109
+
110
+ * `api.send(channel, id, fn, priority)`: Adds a data transformer to a specific channel.
111
+ * `api.receive(channel, initialData)`: Pipes data through all transformers in the channel.
112
+
113
+ #### **State Management**
114
+
115
+ * `useSelector(selector)`: Reactively listen to state changes.
116
+ * `api.update(key, updater)`: Update store data using Immer-powered drafts.
package/index.d.ts CHANGED
@@ -1,10 +1 @@
1
1
  export * from "./types/plug-code";
2
- export * from "./types/core/plcAPI";
3
- export * from "./types/core/plcStore";
4
- export * from "./types/contexts/pipeline";
5
-
6
- export * from "./types/types/api";
7
- export * from "./types/types/features";
8
- export * from "./types/types/general";
9
- export * from "./types/types/pipeline";
10
- export * from "./types/types/store";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plug-code",
3
- "version": "1.0.3",
3
+ "version": "1.1.1",
4
4
  "description": "",
5
5
  "main": "src/plug-code.tsx",
6
6
  "types": "types/plug-code.d.ts",
@@ -3,22 +3,57 @@ import type { ObjectType } from "../types/general";
3
3
  import { useEffect, useState } from "react";
4
4
  import { PlcPipeline } from "./plcPipeline";
5
5
  import type { PlcStore } from "./plcStore";
6
- import type { transformerType } from "../types/api";
6
+ import type { CommandFn, transformerType } from "../types/api";
7
+
8
+ import type { ChannelRegistry, CommandRegistry, SlotRegistry } from "../types/registry";
9
+
10
+ type ChannelKey = keyof ChannelRegistry | (string & {});
11
+ type ChannelData<K> = K extends keyof ChannelRegistry ? ChannelRegistry[K] : any;
12
+
13
+ type CommandKey = keyof CommandRegistry | (string & {});
14
+ type CommandPayload<K> = K extends keyof CommandRegistry
15
+ ? (CommandRegistry[K] extends { payload: infer P } ? P : any)
16
+ : any;
17
+ type CommandResult<K> = K extends keyof CommandRegistry
18
+ ? (CommandRegistry[K] extends { result: infer R } ? R : any)
19
+ : any;
20
+
21
+ type SlotKey = keyof SlotRegistry | (string & {});
22
+
7
23
 
8
24
  export class PlcAPI<S extends ObjectType> {
9
25
  private store: PlcStore<S>
10
26
  private pipeline: PlcPipeline<S>
11
27
  private substores = new Map<string, any>()
12
- private transformers: transformerType[] = []
28
+
29
+ private transformers = new Map<string, transformerType[]>()
30
+ private commands = new Map<string, CommandFn>();
31
+ private installedFeatures = new Set<string>();
13
32
 
14
33
  constructor(store: PlcStore<S>) {
15
34
  this.store = store
16
35
  this.pipeline = new PlcPipeline(store)
17
36
  }
18
37
 
19
- register(slot: string, node: () => React.ReactNode): void;
20
- register<K extends string>(slot: string, node: (data: any) => React.ReactNode, dependencyKey: K): void;
21
- register(slot: string, node: (data?: any) => React.ReactNode, dependencyKey?: string) {
38
+ createFeature(name: string, setupFn: (api: PlcAPI<S>) => void): PlcAPI<S> {
39
+ if (this.installedFeatures.has(name)) {
40
+ console.warn(`[PlcFramework] La feature '${name}' ya fue registrada. Se omitirá para evitar conflictos.`);
41
+ return this;
42
+ }
43
+
44
+ try {
45
+ setupFn(this);
46
+ this.installedFeatures.add(name);
47
+ } catch (error) {
48
+ console.error(`[PlcFramework] 💥 Error crítico inicializando la feature '${name}':`, error);
49
+ }
50
+
51
+ return this;
52
+ }
53
+
54
+ register(slot: SlotKey, node: () => React.ReactNode): void;
55
+ register<K extends string>(slot: SlotKey, node: (data: any) => React.ReactNode, dependencyKey: K): void;
56
+ register(slot: SlotKey, node: (data?: any) => React.ReactNode, dependencyKey?: string) {
22
57
  if (dependencyKey) {
23
58
  const ConnectedWrapper = () => {
24
59
  const [data, setData] = useState(() => this.substores.get(dependencyKey));
@@ -34,12 +69,12 @@ export class PlcAPI<S extends ObjectType> {
34
69
  };
35
70
 
36
71
  this.store.batch(() => {
37
- this.pipeline.register(slot, () => <ConnectedWrapper />);
72
+ this.pipeline.register(slot as string, () => <ConnectedWrapper />);
38
73
  });
39
74
  }
40
75
  else {
41
76
  this.store.batch(() => {
42
- this.pipeline.register(slot, node as () => React.ReactNode);
77
+ this.pipeline.register(slot as string, node as () => React.ReactNode);
43
78
  });
44
79
  }
45
80
  }
@@ -48,7 +83,7 @@ export class PlcAPI<S extends ObjectType> {
48
83
  get: () => T;
49
84
  update: (updater: (draft: T) => void) => void;
50
85
  connect: (renderer: (data: T) => React.ReactNode) => React.FC;
51
- render: (slotName: string) => React.ReactNode | null;
86
+ render: (slotName: SlotKey) => React.ReactNode | null;
52
87
  receive: (context?: any) => any;
53
88
  root: PlcAPI<S>;
54
89
  } {
@@ -63,15 +98,15 @@ export class PlcAPI<S extends ObjectType> {
63
98
  return this.connect(key, renderer);
64
99
  },
65
100
 
66
- render: (slotName: string) => {
101
+ render: (slotName: SlotKey) => {
67
102
  return this.connect(key, (localData) => {
68
- return this.pipeline.render(slotName, localData) as React.ReactNode;
103
+ return this.pipeline.render(slotName as string, localData) as React.ReactNode;
69
104
  }) as any;
70
105
  },
71
106
 
72
107
  receive: (context: any = {}) => {
73
108
  const currentData = this.getData(key);
74
- return this.receive(currentData, context);
109
+ return this.receive(key as any, currentData, context);
75
110
  },
76
111
 
77
112
  root: this
@@ -97,43 +132,105 @@ export class PlcAPI<S extends ObjectType> {
97
132
  };
98
133
  }
99
134
 
100
- wrap(slot: string, fn: (next: () => React.ReactNode) => () => React.ReactNode) {
135
+ wrap(slot: SlotKey, fn: (next: () => React.ReactNode) => () => React.ReactNode) {
101
136
  this.store.batch(() => {
102
- this.pipeline.wrap(slot, fn)
137
+ this.pipeline.wrap(slot as string, fn)
103
138
  })
104
139
  }
105
140
 
106
- after(slot: string, node: () => React.ReactNode) {
141
+ after(slot: SlotKey, node: () => React.ReactNode) {
107
142
  this.store.batch(() => {
108
- this.pipeline.register(slot, node)
143
+ this.pipeline.register(slot as string, node)
109
144
  })
110
145
  }
111
146
 
112
- render(slot: string) {
113
- return this.pipeline.render(slot)
147
+ render(slot: SlotKey) {
148
+ return this.pipeline.render(slot as string)
114
149
  }
115
150
 
116
- invalidate(slot?: string) {
117
- this.pipeline.invalidate(slot)
151
+ invalidate(slot?: SlotKey) {
152
+ this.pipeline.invalidate(slot as string)
118
153
  }
119
154
 
120
- send(id: string, fn: (data: any, context: any) => any, priority: number) {
121
- this.transformers.push({ id, priority, fn });
122
- this.transformers.sort((a, b) => a.priority - b.priority);
155
+ send<K extends ChannelKey>(
156
+ channel: K,
157
+ id: string,
158
+ fn: (data: ChannelData<K>, context: any) => ChannelData<K>,
159
+ priority: number = 0
160
+ ) {
161
+ const channelStr = channel as string;
162
+ if (!this.transformers.has(channelStr)) {
163
+ this.transformers.set(channelStr, []);
164
+ }
165
+
166
+ const channelList = this.transformers.get(channelStr)!;
167
+
168
+ const existingIdx = channelList.findIndex(t => t.id === id);
169
+ if (existingIdx >= 0) {
170
+ channelList[existingIdx] = { id, priority, fn };
171
+ } else {
172
+ channelList.push({ id, priority, fn });
173
+ }
174
+
175
+ channelList.sort((a, b) => a.priority - b.priority);
123
176
  }
124
177
 
125
- receive(initialData: any, context: any = {}) {
178
+ receive<K extends ChannelKey>(
179
+ channel: K,
180
+ initialData: ChannelData<K>,
181
+ context: any = {}
182
+ ): ChannelData<K> {
126
183
  let currentData = initialData;
184
+ const channelList = this.transformers.get(channel as string) || [];
127
185
 
128
- for (const transformer of this.transformers) {
186
+ for (const transformer of channelList) {
129
187
  try {
130
188
  currentData = transformer.fn(currentData, context);
131
189
  } catch (error) {
132
- console.error(`[Pipeline] Error en transformador '${transformer.id}':`, error);
190
+ console.error(`[PlcAPI] Error en transform '${channel as string}/${transformer.id}':`, error);
133
191
  }
134
192
  }
135
193
 
136
- return currentData;
194
+ return currentData as ChannelData<K>;
195
+ }
196
+
197
+ registerCommand<K extends CommandKey>(
198
+ id: K,
199
+ fn: CommandFn<CommandPayload<K>, CommandResult<K>>
200
+ ) {
201
+ if (this.commands.has(id as string)) {
202
+ console.warn(`[PlcAPI] Sobrescribiendo comando '${id as string}'`);
203
+ }
204
+ this.commands.set(id as string, fn as any);
205
+ }
206
+
207
+ wrapCommand<K extends CommandKey>(
208
+ id: K,
209
+ wrapper: (next: CommandFn<CommandPayload<K>, CommandResult<K>>) => CommandFn<CommandPayload<K>, CommandResult<K>>
210
+ ) {
211
+ const currentFn = this.commands.get(id as string);
212
+ if (!currentFn) {
213
+ console.error(`[PlcAPI] No se puede envolver '${id as string}', comando no existe.`);
214
+ return;
215
+ }
216
+ this.commands.set(id as string, wrapper(currentFn) as any);
217
+ }
218
+
219
+ async execute<K extends CommandKey>(
220
+ id: K,
221
+ payload?: CommandPayload<K>
222
+ ): Promise<CommandResult<K>> {
223
+ const fn = this.commands.get(id as string);
224
+ if (!fn) {
225
+ throw new Error(`[PlcAPI] Comando '${id as string}' no encontrado.`);
226
+ }
227
+
228
+ try {
229
+ return await fn(payload);
230
+ } catch (error) {
231
+ console.error(`[PlcAPI] Error ejecutando '${id as string}':`, error);
232
+ throw error;
233
+ }
137
234
  }
138
235
 
139
236
  getData(key: string): any {
package/src/plug-code.tsx CHANGED
@@ -1,15 +1,16 @@
1
1
  import { enableMapSet } from "immer";
2
2
  import type { ObjectType } from "./types/general";
3
- import type { FeatureType } from "./types/features";
4
3
  import { PlcAPI } from "./core/plcAPI";
5
4
  import { useEffect, useMemo, useState } from "react";
6
5
  import { PlcStore } from "./core/plcStore";
7
6
 
8
- enableMapSet()
9
- export function createPlugAndCode<S extends ObjectType>(features: FeatureType<S>[]) {
7
+ enableMapSet();
8
+
9
+ export function createPlugAndCode<S extends ObjectType>(
10
+ setupSystem: (api: PlcAPI<S>) => void
11
+ ) {
10
12
  const FeatureHost = ({ api, children }: { api: PlcAPI<any>, children?: React.ReactNode }) => (
11
13
  <>
12
- {/* Renderizamos el slot principal */}
13
14
  {api.render("root")}
14
15
  {children}
15
16
  </>
@@ -32,9 +33,7 @@ export function createPlugAndCode<S extends ObjectType>(features: FeatureType<S>
32
33
 
33
34
  api.createData("root", initialProps);
34
35
 
35
- for (const feature of features) {
36
- feature.setup?.(api as any);
37
- }
36
+ setupSystem(api as unknown as PlcAPI<S>);
38
37
 
39
38
  return api;
40
39
  }, []);
package/src/types/api.ts CHANGED
@@ -1,2 +1,8 @@
1
1
 
2
- export type transformerType = { id: string, priority: number, fn: (data: any, context: any) => any }
2
+ export type transformerType = {
3
+ id: string,
4
+ priority: number,
5
+ fn: (data: any, context: any) => any
6
+ }
7
+
8
+ export type CommandFn<T = any, R = any> = (payload: T) => Promise<R> | R;
@@ -0,0 +1,4 @@
1
+
2
+ export interface ChannelRegistry {}
3
+ export interface CommandRegistry {}
4
+ export interface SlotRegistry {}
@@ -1,13 +1,156 @@
1
- import type { ObjectType } from "./types/general";
2
- import type { FeatureType } from "./types/features";
3
- import { PlcAPI } from "./core/plcAPI";
4
- export declare function createPlugAndCode<S extends ObjectType>(features: FeatureType<S>[]): {
5
- useSystemPlc: <T extends object>(initialProps: T) => {
6
- api: PlcAPI<{}>;
7
- useSelector: <Result>(selector: (state: any) => Result) => Result;
8
- };
9
- SystemPlcRoot: ({ api, children }: {
10
- api: PlcAPI<any>;
11
- children?: React.ReactNode;
12
- }) => import("react/jsx-runtime").JSX.Element;
13
- };
1
+ import * as React from 'react';
2
+
3
+ // ==========================================
4
+ // Tipos Generales
5
+ // ==========================================
6
+
7
+ export type ObjectType = Record<string, any>;
8
+
9
+ export type Slot = () => React.ReactNode;
10
+
11
+ /**
12
+ * Función para ejecutar lógica de negocio (Acciones).
13
+ * Puede ser síncrona o asíncrona.
14
+ */
15
+ export type CommandFn<T = any, R = any> = (payload: T) => Promise<R> | R;
16
+
17
+ /**
18
+ * Función para transformar datos (Pipes).
19
+ * Debe ser pura y síncrona preferiblemente.
20
+ */
21
+ export type TransformerFn<D = any, C = any> = (data: D, context: C) => D;
22
+
23
+ // ==========================================
24
+ // Core: Store
25
+ // ==========================================
26
+
27
+ export declare class PlcStore<S extends ObjectType> {
28
+ constructor(initial: S, debug: boolean);
29
+
30
+ get<K extends keyof S>(key: K): S[K];
31
+ getState(): S;
32
+ set<K extends keyof S>(key: K, value: S[K]): void;
33
+
34
+ /** Agrupa múltiples actualizaciones en un solo evento de notificación */
35
+ batch(updater: (draft: S) => void): void;
36
+
37
+ subscribe(listener: () => void): () => void;
38
+ subscribe<K extends keyof S>(key: K, listener: () => void): () => void;
39
+ }
40
+
41
+ // ==========================================
42
+ // Core: API Principal
43
+ // ==========================================
44
+
45
+ export declare class PlcAPI<S extends ObjectType> {
46
+ constructor(store: PlcStore<S>);
47
+
48
+ // --- Configuración del Sistema (Fluent Interface) ---
49
+
50
+ /**
51
+ * Registra un módulo o feature en el sistema.
52
+ * @param name Identificador único para debugging y prevención de duplicados.
53
+ * @param setupFn Función de configuración donde registras slots, comandos, etc.
54
+ */
55
+ feature(name: string, setupFn: (api: PlcAPI<S>) => void): PlcAPI<S>;
56
+
57
+ // --- Gestión de UI (Slots & Rendering) ---
58
+
59
+ register(slot: string, node: () => React.ReactNode): void;
60
+ register<K extends string>(slot: string, node: (data: any) => React.ReactNode, dependencyKey: K): void;
61
+
62
+ /** Envuelve un slot existente (Decorador/Wrapper) */
63
+ wrap(slot: string, fn: (next: () => React.ReactNode) => () => React.ReactNode): void;
64
+
65
+ /** Agrega contenido después de un slot existente */
66
+ after(slot: string, node: () => React.ReactNode): void;
67
+
68
+ /** Renderiza el contenido de un slot */
69
+ render(slot: string, contextData?: any): React.ReactNode;
70
+
71
+ /** Fuerza la regeneración del caché de un slot */
72
+ invalidate(slot?: string): void;
73
+
74
+ // --- Gestión de Datos (Scope & State) ---
75
+
76
+ createData<K extends string, T>(key: K, initialState: T): void;
77
+
78
+ getData(key: string): any;
79
+
80
+ update<K extends keyof S>(key: string & "root", updater: (draft: any) => void, slot?: string): void;
81
+
82
+ subscribe(listener: () => void): () => void;
83
+
84
+ /**
85
+ * Obtiene una interfaz tipada para interactuar con una parte específica del estado.
86
+ */
87
+ scope<T = any>(key: string): {
88
+ get: () => T;
89
+ update: (updater: (draft: T) => void) => void;
90
+ connect: (renderer: (data: T) => React.ReactNode) => React.FC;
91
+ render: (slotName: string) => React.ReactNode | null;
92
+ receive: (context?: any) => any;
93
+ root: PlcAPI<S>;
94
+ };
95
+
96
+ /** Conecta un componente a una parte del estado (HOC) */
97
+ connect<T = any>(key: string, renderer: (data: T) => React.ReactNode): React.FC;
98
+
99
+ // --- Pipeline de Datos (Transforms) ---
100
+
101
+ /**
102
+ * Registra un transformador en un canal específico.
103
+ * @param channel Nombre del canal (ej: 'calculo-impuestos')
104
+ * @param id Identificador único del transformador
105
+ * @param fn Función transformadora
106
+ * @param priority Mayor número se ejecuta al final (default: 0)
107
+ */
108
+ send(channel: string, id: string, fn: TransformerFn, priority?: number): void;
109
+
110
+ /**
111
+ * Ejecuta la tubería de transformación para un canal.
112
+ */
113
+ receive(channel: string, initialData: any, context?: any): any;
114
+
115
+ // --- Sistema de Comandos (Actions) ---
116
+
117
+ /**
118
+ * Registra una acción ejecutable.
119
+ */
120
+ registerCommand<T = any, R = any>(id: string, fn: CommandFn<T, R>): void;
121
+
122
+ /**
123
+ * Envuelve o intercepta un comando existente.
124
+ */
125
+ wrapCommand<T = any, R = any>(id: string, wrapper: (next: CommandFn<T, R>) => CommandFn<T, R>): void;
126
+
127
+ /**
128
+ * Ejecuta una acción registrada.
129
+ * @returns Promesa con el resultado del comando.
130
+ */
131
+ execute<T = any, R = any>(id: string, payload?: T): Promise<R>;
132
+ }
133
+
134
+ // ==========================================
135
+ // Entry Point & Hooks
136
+ // ==========================================
137
+
138
+ export type SystemInstance<S extends ObjectType> = {
139
+ api: PlcAPI<S>;
140
+ /** Hook para seleccionar datos del store reactivamente */
141
+ useSelector: <Result>(selector: (state: S) => Result) => Result;
142
+ };
143
+
144
+ /**
145
+ * Inicializa el framework.
146
+ * @param setupSystem Función callback para configurar las features iniciales.
147
+ */
148
+ export declare function createPlugAndCode<S extends ObjectType>(
149
+ setupSystem: (api: PlcAPI<S>) => void
150
+ ): {
151
+ useSystemPlc: (initialProps: S) => SystemInstance<S>;
152
+ SystemPlcRoot: React.FC<{ api: PlcAPI<S>; children?: React.ReactNode }>;
153
+ };
154
+
155
+ /** Hook para acceder al contexto local dentro de un slot renderizado */
156
+ export declare function useScopeData<T>(): T;
@@ -1,2 +0,0 @@
1
- export declare const ScopeContext: import("react").Context<any>;
2
- export declare const useScopeData: <T>() => T;
@@ -1,30 +0,0 @@
1
- import type { ObjectType } from "../types/general";
2
- import type { PlcStore } from "./plcStore";
3
- export declare class PlcAPI<S extends ObjectType> {
4
- private store;
5
- private pipeline;
6
- private substores;
7
- private transformers;
8
- constructor(store: PlcStore<S>);
9
- register(slot: string, node: () => React.ReactNode): void;
10
- register<K extends string>(slot: string, node: (data: any) => React.ReactNode, dependencyKey: K): void;
11
- scope<T = any>(key: string & "root"): {
12
- get: () => T;
13
- update: (updater: (draft: T) => void) => void;
14
- connect: (renderer: (data: T) => React.ReactNode) => React.FC;
15
- render: (slotName: string) => React.ReactNode | null;
16
- receive: (context?: any) => any;
17
- root: PlcAPI<S>;
18
- };
19
- connect<T = any>(key: string, renderer: (data: T) => React.ReactNode): React.FC;
20
- wrap(slot: string, fn: (next: () => React.ReactNode) => () => React.ReactNode): void;
21
- after(slot: string, node: () => React.ReactNode): void;
22
- render(slot: string): import("react").ReactNode[] | import("react/jsx-runtime").JSX.Element;
23
- invalidate(slot?: string): void;
24
- send(id: string, fn: (data: any, context: any) => any, priority: number): void;
25
- receive(initialData: any, context?: any): any;
26
- getData(key: string): any;
27
- subscribe(listener: () => void): () => void;
28
- createData<K extends string, T>(key: K, initialState: T): void;
29
- update<K extends keyof S>(key: string & "root", updater: (draft: any) => void, slot?: string): void;
30
- }
@@ -1,16 +0,0 @@
1
- import React from "react";
2
- import type { ObjectType } from "../types/general";
3
- import type { Slot } from "../types/pipeline";
4
- import type { PlcStore } from "./plcStore";
5
- export declare class PlcPipeline<S extends ObjectType> {
6
- private slots;
7
- private store;
8
- private cache;
9
- private scheduleQueue;
10
- constructor(store: PlcStore<S>);
11
- register(slot: string, fn: Slot, priority?: number): void;
12
- wrap(slot: string, wrapper: (next: Slot) => Slot, priority?: number): void;
13
- render(slot: string, contextData?: any): React.ReactNode[] | import("react/jsx-runtime").JSX.Element;
14
- invalidate(slot?: string): void;
15
- private regenerateCache;
16
- }
@@ -1,17 +0,0 @@
1
- import { type Draft } from "immer";
2
- import type { ObjectType } from "../types/general";
3
- export declare class PlcStore<S extends ObjectType> {
4
- private state;
5
- private listeners;
6
- private batchQueue;
7
- private debug;
8
- private isBatching;
9
- constructor(initial: S, debug: boolean);
10
- get<K extends keyof S>(key: K): S[K];
11
- getState(): S;
12
- set<K extends keyof S>(key: K, value: S[K]): void;
13
- batch(updater: (draft: Draft<S>) => void): void;
14
- subscribe(listener: () => void): () => void;
15
- subscribe<K extends keyof S>(key: K, listener: () => void): () => void;
16
- private emit;
17
- }
@@ -1,5 +0,0 @@
1
- export type transformerType = {
2
- id: string;
3
- priority: number;
4
- fn: (data: any, context: any) => any;
5
- };
@@ -1,6 +0,0 @@
1
- import type { PlcAPI } from "../core/plcAPI";
2
- import type { ObjectType } from "./general";
3
- export type FeatureType<S extends ObjectType> = {
4
- name: string;
5
- setup?: (api: PlcAPI<S>) => void | (() => void);
6
- };
@@ -1 +0,0 @@
1
- export type ObjectType = Record<string, any>;
@@ -1,6 +0,0 @@
1
- export type Slot = () => React.ReactNode;
2
- export type ScheduledSlot = {
3
- slot: string;
4
- fn: Slot;
5
- priority: number;
6
- };
@@ -1,4 +0,0 @@
1
- export type Listener<S> = {
2
- key?: keyof S;
3
- callback: () => void;
4
- };