@plures/praxis 1.1.3 → 1.2.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/FRAMEWORK.md +106 -15
- package/README.md +209 -48
- package/dist/browser/adapter-TM4IS5KT.js +12 -0
- package/dist/browser/chunk-JQ64KMLN.js +141 -0
- package/dist/browser/chunk-LE2ZJYFC.js +154 -0
- package/dist/browser/{chunk-R45WXWKH.js → chunk-VOMLVI6V.js} +1 -149
- package/dist/browser/engine-YJZV4SLD.js +8 -0
- package/dist/browser/index.d.ts +130 -1
- package/dist/browser/index.js +146 -139
- package/dist/browser/integrations/svelte.js +2 -1
- package/dist/node/adapter-K6DOX6XS.js +13 -0
- package/dist/node/chunk-JQ64KMLN.js +141 -0
- package/dist/node/chunk-LE2ZJYFC.js +154 -0
- package/dist/node/chunk-S54337I5.js +446 -0
- package/dist/node/{chunk-R45WXWKH.js → chunk-VOMLVI6V.js} +1 -149
- package/dist/node/cli/index.cjs +1444 -889
- package/dist/node/cli/index.js +9 -0
- package/dist/node/docs-JFNYTOJA.js +102 -0
- package/dist/node/engine-2DQBKBJC.js +9 -0
- package/dist/node/index.cjs +503 -325
- package/dist/node/index.d.cts +130 -1
- package/dist/node/index.d.ts +130 -1
- package/dist/node/index.js +151 -580
- package/dist/node/integrations/svelte.js +2 -1
- package/package.json +1 -1
- package/src/cli/commands/docs.ts +147 -0
- package/src/cli/index.ts +21 -0
- package/src/core/pluresdb/adapter.ts +1 -1
- package/src/core/reactive-engine.svelte.ts +6 -1
- package/src/core/reactive-engine.ts +1 -1
- package/src/index.browser.ts +4 -0
- package/src/index.ts +4 -0
- package/src/integrations/unified.ts +350 -0
package/FRAMEWORK.md
CHANGED
|
@@ -143,28 +143,104 @@ PluresDB provides the data storage and synchronization layer.
|
|
|
143
143
|
- Logic engine fact/event storage
|
|
144
144
|
- Component data binding
|
|
145
145
|
- Distributed state management
|
|
146
|
+
- CRDT-based synchronization
|
|
147
|
+
- Event sourcing and replay
|
|
146
148
|
|
|
147
|
-
|
|
149
|
+
**Status**: ✅ Fully implemented with comprehensive test coverage
|
|
148
150
|
|
|
149
|
-
|
|
151
|
+
### 5. Identity & Channels (Unum Integration)
|
|
152
|
+
|
|
153
|
+
Unum provides identity management and channel-based communication for distributed systems.
|
|
150
154
|
|
|
151
155
|
**Features:**
|
|
152
156
|
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
157
|
+
- Identity creation and management
|
|
158
|
+
- Channel-based messaging
|
|
159
|
+
- Event and fact broadcasting
|
|
160
|
+
- Member management
|
|
161
|
+
- Real-time synchronization with PluresDB
|
|
162
|
+
|
|
163
|
+
**Use Cases:**
|
|
164
|
+
|
|
165
|
+
- Multi-user collaboration
|
|
166
|
+
- Distributed event streaming
|
|
167
|
+
- Node-to-node communication
|
|
168
|
+
- Identity-based access control
|
|
169
|
+
- Real-time state synchronization
|
|
170
|
+
|
|
171
|
+
**Integration Points:**
|
|
172
|
+
|
|
173
|
+
- Praxis event broadcasting to channels
|
|
174
|
+
- Fact synchronization across nodes
|
|
175
|
+
- PluresDB backend for persistence
|
|
176
|
+
- Engine attachment for automatic distribution
|
|
177
|
+
|
|
178
|
+
**Status**: ✅ Fully implemented with comprehensive API
|
|
179
|
+
|
|
180
|
+
### 6. Documentation (State-Docs Integration)
|
|
181
|
+
|
|
182
|
+
State-Docs generates living documentation from Praxis schemas and logic definitions.
|
|
183
|
+
|
|
184
|
+
**Features:**
|
|
185
|
+
|
|
186
|
+
- Auto-generated Markdown documentation
|
|
187
|
+
- Mermaid and DOT diagram generation
|
|
188
|
+
- Model and component catalogs
|
|
189
|
+
- Logic flow visualization
|
|
190
|
+
- Event → Rule → Fact diagrams
|
|
191
|
+
- Customizable templates
|
|
192
|
+
|
|
193
|
+
**Use Cases:**
|
|
194
|
+
|
|
195
|
+
- API documentation
|
|
196
|
+
- Architecture diagrams
|
|
197
|
+
- Onboarding documentation
|
|
198
|
+
- Design reviews
|
|
199
|
+
- GitHub Pages integration
|
|
200
|
+
|
|
201
|
+
**Integration Points:**
|
|
202
|
+
|
|
203
|
+
- Schema documentation generation
|
|
204
|
+
- Registry introspection
|
|
205
|
+
- Automatic ToC and index generation
|
|
206
|
+
- Diagram export (Mermaid, DOT)
|
|
207
|
+
|
|
208
|
+
**Status**: ✅ Fully implemented with CLI support (`praxis docs`)
|
|
209
|
+
|
|
210
|
+
### 7. Visual IDE (CodeCanvas Integration)
|
|
211
|
+
|
|
212
|
+
CodeCanvas provides visual development capabilities for schemas and logic flows.
|
|
213
|
+
|
|
214
|
+
**Features:**
|
|
215
|
+
|
|
216
|
+
- Visual schema editor with node-based UI
|
|
217
|
+
- Schema ↔ Canvas bi-directional sync
|
|
218
|
+
- Mermaid and YAML export
|
|
219
|
+
- Obsidian Canvas compatibility
|
|
220
|
+
- FSM visualization
|
|
221
|
+
- Guardian pre-commit validation
|
|
222
|
+
- Activity lifecycle tracking
|
|
158
223
|
|
|
159
224
|
**Use Cases:**
|
|
160
225
|
|
|
161
226
|
- Design schemas visually
|
|
162
|
-
- Build logic flows with
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
227
|
+
- Build logic flows with visual tools
|
|
228
|
+
- Export schemas to diagrams
|
|
229
|
+
- Integrate with Obsidian workflows
|
|
230
|
+
- Visualize state machines
|
|
231
|
+
- Enforce development lifecycle
|
|
166
232
|
|
|
167
|
-
|
|
233
|
+
**Integration Points:**
|
|
234
|
+
|
|
235
|
+
- Schema conversion (`schemaToCanvas`)
|
|
236
|
+
- Canvas export (YAML, Mermaid, JSON)
|
|
237
|
+
- Visual editor API
|
|
238
|
+
- FSM lifecycle management
|
|
239
|
+
- Guardian validation hooks
|
|
240
|
+
|
|
241
|
+
**Status**: ✅ Fully implemented with CLI support (`praxis canvas`)
|
|
242
|
+
|
|
243
|
+
### 8. Orchestration (DSC/MCP Support)
|
|
168
244
|
|
|
169
245
|
Support for distributed system coordination.
|
|
170
246
|
|
|
@@ -213,17 +289,32 @@ Generate code from schemas.
|
|
|
213
289
|
|
|
214
290
|
Options:
|
|
215
291
|
|
|
216
|
-
- `--target`: Generation target (components, models, docs, all)
|
|
292
|
+
- `--target`: Generation target (components, models, pluresdb, docs, all)
|
|
217
293
|
- `--watch`: Watch for schema changes
|
|
294
|
+
- `--auto-index`: Auto-indexing strategy for PluresDB
|
|
295
|
+
|
|
296
|
+
#### `praxis docs [schema]`
|
|
297
|
+
|
|
298
|
+
Generate documentation from schemas or registries.
|
|
299
|
+
|
|
300
|
+
Options:
|
|
301
|
+
|
|
302
|
+
- `--output`: Output directory (default: ./docs)
|
|
303
|
+
- `--title`: Documentation title
|
|
304
|
+
- `--format`: Diagram format (mermaid, dot)
|
|
305
|
+
- `--no-toc`: Disable table of contents
|
|
306
|
+
- `--from-registry`: Generate from registry instead of schema
|
|
218
307
|
|
|
219
308
|
#### `praxis canvas [schema]`
|
|
220
309
|
|
|
221
|
-
Open CodeCanvas for visual editing.
|
|
310
|
+
Open CodeCanvas for visual editing or export schemas to canvas formats.
|
|
222
311
|
|
|
223
312
|
Options:
|
|
224
313
|
|
|
225
|
-
- `--port`: Port for Canvas server
|
|
314
|
+
- `--port`: Port for Canvas server (default: 3000)
|
|
226
315
|
- `--mode`: Mode (edit, view, present)
|
|
316
|
+
- `--export`: Export format (yaml, mermaid, json)
|
|
317
|
+
- `--output`: Output file for export
|
|
227
318
|
|
|
228
319
|
#### `praxis orchestrate`
|
|
229
320
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,16 @@ dotnet test
|
|
|
10
10
|
[](https://nodejs.org/)
|
|
11
11
|
[](https://deno.land/)
|
|
12
12
|
|
|
13
|
-
Praxis is
|
|
13
|
+
Praxis is **the unified solution for declarative application development**, combining:
|
|
14
|
+
|
|
15
|
+
- **Logic Modeling**: Typed facts, events, rules, and constraints for domain logic
|
|
16
|
+
- **Component Auto-Generation**: Svelte 5 components generated from schemas
|
|
17
|
+
- **Data Persistence**: PluresDB for local-first, reactive data storage
|
|
18
|
+
- **Documentation**: Auto-generated docs with State-Docs and visual diagrams
|
|
19
|
+
- **Visual Editing**: CodeCanvas for schema design and FSM visualization
|
|
20
|
+
- **Distributed Systems**: Unum for identity and multi-node communication
|
|
21
|
+
|
|
22
|
+
The library delivers a unified ESM/CJS build, curated subpath exports, Svelte runes support, and a slimmer, publish-ready package for npm and JSR.
|
|
14
23
|
|
|
15
24
|
---
|
|
16
25
|
|
|
@@ -26,9 +35,12 @@ Praxis is a schema-driven, rule-based engine with first-class Svelte 5 integrati
|
|
|
26
35
|
- **Logic Engine**: Facts, events, rules, constraints, registry, introspection, and reactive engine variants (Svelte 5 + framework-agnostic).
|
|
27
36
|
- **Schema & Codegen**: PSF-style schema types plus component generator for Svelte UIs.
|
|
28
37
|
- **Svelte Integration**: Typed helpers, runes-ready builds, and Svelte component typings.
|
|
29
|
-
- **Local-First Data**: PluresDB
|
|
38
|
+
- **Local-First Data**: PluresDB integration for offline-first, reactive state with full persistence.
|
|
39
|
+
- **Distributed Systems**: Unum integration for identity management and multi-node channels.
|
|
40
|
+
- **Documentation**: State-Docs integration for auto-generated Markdown docs and Mermaid diagrams.
|
|
41
|
+
- **Visual Editing**: CodeCanvas integration for visual schema design and FSM visualization.
|
|
30
42
|
- **Cloud Relay**: Optional sync layer (GitHub-auth friendly) for distributed teams.
|
|
31
|
-
- **CLI**: Scaffolding, generation, canvas helpers, and cloud commands.
|
|
43
|
+
- **CLI**: Scaffolding, generation, canvas helpers, docs generation, and cloud commands.
|
|
32
44
|
|
|
33
45
|
## Install
|
|
34
46
|
Node 18+ recommended.
|
|
@@ -81,6 +93,64 @@ const engine = createPraxisEngine({ initialContext: { currentUser: null }, regis
|
|
|
81
93
|
engine.step([Login.create({ username: 'alex' })]);
|
|
82
94
|
```
|
|
83
95
|
|
|
96
|
+
## Unified workflow example
|
|
97
|
+
|
|
98
|
+
See all Praxis integrations working together - from schema definition to persistence, documentation, and distributed communication:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import {
|
|
102
|
+
createPraxisEngine,
|
|
103
|
+
PraxisRegistry,
|
|
104
|
+
defineRule,
|
|
105
|
+
createInMemoryDB,
|
|
106
|
+
createPluresDBAdapter,
|
|
107
|
+
createUnumAdapter,
|
|
108
|
+
createStateDocsGenerator,
|
|
109
|
+
schemaToCanvas,
|
|
110
|
+
} from '@plures/praxis';
|
|
111
|
+
|
|
112
|
+
// 1. Define logic with Praxis engine
|
|
113
|
+
const registry = new PraxisRegistry();
|
|
114
|
+
registry.registerRule(/* your rules */);
|
|
115
|
+
const engine = createPraxisEngine({ initialContext: {}, registry });
|
|
116
|
+
|
|
117
|
+
// 2. Add PluresDB for local-first persistence
|
|
118
|
+
const db = createInMemoryDB();
|
|
119
|
+
const pluresAdapter = createPluresDBAdapter({ db, registry });
|
|
120
|
+
pluresAdapter.attachEngine(engine);
|
|
121
|
+
|
|
122
|
+
// 3. Add Unum for distributed communication
|
|
123
|
+
const unum = await createUnumAdapter({
|
|
124
|
+
db,
|
|
125
|
+
identity: { name: 'node-1' },
|
|
126
|
+
realtime: true,
|
|
127
|
+
});
|
|
128
|
+
const channel = await unum.createChannel('app-sync');
|
|
129
|
+
|
|
130
|
+
// Subscribe to distribute events across nodes
|
|
131
|
+
unum.subscribeToEvents(channel.id, (event) => {
|
|
132
|
+
engine.step([event]);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// 4. Generate documentation with State-Docs
|
|
136
|
+
const docsGenerator = createStateDocsGenerator({
|
|
137
|
+
projectTitle: 'My App',
|
|
138
|
+
target: './docs',
|
|
139
|
+
});
|
|
140
|
+
const docs = docsGenerator.generateFromModule(registry.module);
|
|
141
|
+
|
|
142
|
+
// 5. Export schema to CodeCanvas for visual editing
|
|
143
|
+
const canvas = schemaToCanvas(mySchema);
|
|
144
|
+
// Canvas can be edited visually and converted back to schema
|
|
145
|
+
|
|
146
|
+
// Now you have:
|
|
147
|
+
// ✅ Logic engine running
|
|
148
|
+
// ✅ Auto-persisting to PluresDB
|
|
149
|
+
// ✅ Distributing events across nodes via Unum
|
|
150
|
+
// ✅ Auto-generated documentation
|
|
151
|
+
// ✅ Visual schema representation
|
|
152
|
+
```
|
|
153
|
+
|
|
84
154
|
## Svelte integration (runes-ready)
|
|
85
155
|
```svelte
|
|
86
156
|
<script lang="ts">
|
|
@@ -652,32 +722,55 @@ adapter.subscribeToEvents((events) => {
|
|
|
652
722
|
|
|
653
723
|
### Unum Integration
|
|
654
724
|
|
|
655
|
-
Identity and channels for distributed systems.
|
|
725
|
+
Identity and channels for distributed systems. **Now fully implemented** with comprehensive channel and identity management.
|
|
656
726
|
|
|
657
727
|
```typescript
|
|
658
|
-
import {
|
|
728
|
+
import {
|
|
729
|
+
createUnumAdapter,
|
|
730
|
+
attachUnumToEngine,
|
|
731
|
+
} from '@plures/praxis';
|
|
659
732
|
|
|
660
|
-
// Create identity
|
|
661
|
-
const
|
|
662
|
-
|
|
663
|
-
|
|
733
|
+
// Create Unum adapter with identity
|
|
734
|
+
const unum = await createUnumAdapter({
|
|
735
|
+
db: pluresDB,
|
|
736
|
+
identity: {
|
|
737
|
+
name: 'my-app-node',
|
|
738
|
+
metadata: { role: 'coordinator' },
|
|
739
|
+
},
|
|
740
|
+
realtime: true,
|
|
664
741
|
});
|
|
665
742
|
|
|
666
|
-
// Create channel for messaging
|
|
667
|
-
const channel = await createChannel(
|
|
668
|
-
|
|
669
|
-
|
|
743
|
+
// Create a channel for messaging
|
|
744
|
+
const channel = await unum.createChannel('app-events', ['member-1', 'member-2']);
|
|
745
|
+
|
|
746
|
+
// Broadcast Praxis events to channel
|
|
747
|
+
await unum.broadcastEvent(channel.id, {
|
|
748
|
+
tag: 'USER_JOINED',
|
|
749
|
+
payload: { userId: 'alice' },
|
|
670
750
|
});
|
|
671
751
|
|
|
672
|
-
//
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
|
|
752
|
+
// Subscribe to events from channel
|
|
753
|
+
const unsubscribe = unum.subscribeToEvents(channel.id, (event) => {
|
|
754
|
+
console.log('Received event:', event);
|
|
755
|
+
// Feed into local Praxis engine
|
|
756
|
+
engine.step([event]);
|
|
676
757
|
});
|
|
758
|
+
|
|
759
|
+
// Attach to engine for automatic event broadcasting
|
|
760
|
+
attachUnumToEngine(engine, unum, channel.id);
|
|
677
761
|
```
|
|
678
762
|
|
|
679
|
-
**
|
|
680
|
-
|
|
763
|
+
**Features:**
|
|
764
|
+
|
|
765
|
+
- **Identity Management**: Create and manage user/node identities
|
|
766
|
+
- **Channel Communication**: Real-time messaging between distributed nodes
|
|
767
|
+
- **Event Broadcasting**: Share Praxis events across channels
|
|
768
|
+
- **Fact Synchronization**: Distribute facts to connected participants
|
|
769
|
+
- **PluresDB Integration**: Persists identities and messages
|
|
770
|
+
|
|
771
|
+
**Status**: ✅ Available (`src/integrations/unum.ts`)
|
|
772
|
+
**Tests**: Comprehensive integration tests
|
|
773
|
+
**Use Cases**: Distributed messaging, identity management, multi-user collaboration
|
|
681
774
|
|
|
682
775
|
### ADP Integration
|
|
683
776
|
|
|
@@ -712,48 +805,116 @@ adp.enforce({
|
|
|
712
805
|
|
|
713
806
|
### State-Docs Integration
|
|
714
807
|
|
|
715
|
-
Living documentation generated from Praxis schemas.
|
|
808
|
+
Living documentation generated from Praxis schemas. **Now fully implemented** with Markdown and Mermaid diagram generation.
|
|
716
809
|
|
|
717
810
|
```typescript
|
|
718
|
-
import {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
811
|
+
import {
|
|
812
|
+
createStateDocsGenerator,
|
|
813
|
+
generateDocs,
|
|
814
|
+
} from '@plures/praxis';
|
|
815
|
+
|
|
816
|
+
// Create generator
|
|
817
|
+
const generator = createStateDocsGenerator({
|
|
818
|
+
projectTitle: 'My Praxis App',
|
|
819
|
+
target: './docs',
|
|
820
|
+
visualization: {
|
|
821
|
+
format: 'mermaid',
|
|
822
|
+
theme: 'default',
|
|
823
|
+
},
|
|
824
|
+
template: {
|
|
825
|
+
toc: true,
|
|
826
|
+
timestamp: true,
|
|
827
|
+
},
|
|
727
828
|
});
|
|
728
829
|
|
|
729
|
-
//
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
//
|
|
733
|
-
|
|
734
|
-
|
|
830
|
+
// Generate docs from schema
|
|
831
|
+
const docs = generator.generateFromSchema(appSchema);
|
|
832
|
+
|
|
833
|
+
// Or from registry
|
|
834
|
+
const registryDocs = generator.generateFromModule(myModule);
|
|
835
|
+
|
|
836
|
+
// Write generated docs
|
|
837
|
+
for (const doc of docs) {
|
|
838
|
+
await writeFile(doc.path, doc.content);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// Quick helper
|
|
842
|
+
const allDocs = generateDocs(appSchema, {
|
|
843
|
+
projectTitle: 'My App',
|
|
844
|
+
target: './docs',
|
|
845
|
+
});
|
|
735
846
|
```
|
|
736
847
|
|
|
737
|
-
**
|
|
738
|
-
|
|
848
|
+
**Features:**
|
|
849
|
+
|
|
850
|
+
- **Schema Documentation**: Auto-generate docs from Praxis schemas
|
|
851
|
+
- **Mermaid Diagrams**: Visual state machine and flow diagrams
|
|
852
|
+
- **Markdown Output**: GitHub-ready documentation
|
|
853
|
+
- **Model & Component Docs**: Detailed API documentation
|
|
854
|
+
- **Logic Flow Visualization**: Event → Rule → Fact diagrams
|
|
855
|
+
- **Table of Contents**: Automatic ToC generation
|
|
856
|
+
|
|
857
|
+
**Status**: ✅ Available (`src/integrations/state-docs.ts`)
|
|
858
|
+
**CLI**: Use `praxis generate` with `--docs` flag (coming soon)
|
|
859
|
+
**Documentation**: Auto-generates README, models.md, logic diagrams
|
|
739
860
|
|
|
740
861
|
### CodeCanvas Integration
|
|
741
862
|
|
|
742
|
-
Visual IDE for schema and logic editing.
|
|
863
|
+
Visual IDE for schema and logic editing. **Now fully implemented** with schema visualization and canvas export.
|
|
743
864
|
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
|
|
865
|
+
```typescript
|
|
866
|
+
import {
|
|
867
|
+
schemaToCanvas,
|
|
868
|
+
canvasToSchema,
|
|
869
|
+
canvasToMermaid,
|
|
870
|
+
createCanvasEditor,
|
|
871
|
+
} from '@plures/praxis';
|
|
872
|
+
|
|
873
|
+
// Convert schema to canvas document
|
|
874
|
+
const canvas = schemaToCanvas(mySchema, {
|
|
875
|
+
layout: 'hierarchical',
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
// Export to YAML (Obsidian Canvas compatible)
|
|
879
|
+
const yaml = canvasToYaml(canvas);
|
|
880
|
+
await writeFile('./schema.canvas.yaml', yaml);
|
|
881
|
+
|
|
882
|
+
// Export to Mermaid diagram
|
|
883
|
+
const mermaid = canvasToMermaid(canvas);
|
|
747
884
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
885
|
+
// Create canvas editor instance
|
|
886
|
+
const editor = createCanvasEditor({
|
|
887
|
+
schema: mySchema,
|
|
888
|
+
enableFSM: true,
|
|
889
|
+
layout: 'hierarchical',
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
// Add nodes programmatically
|
|
893
|
+
editor.addNode({
|
|
894
|
+
type: 'model',
|
|
895
|
+
label: 'User',
|
|
896
|
+
x: 100,
|
|
897
|
+
y: 100,
|
|
898
|
+
width: 150,
|
|
899
|
+
height: 60,
|
|
900
|
+
data: userModel,
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
// Convert back to schema
|
|
904
|
+
const updatedSchema = editor.toSchema();
|
|
754
905
|
```
|
|
755
906
|
|
|
756
|
-
**
|
|
907
|
+
**Features:**
|
|
908
|
+
|
|
909
|
+
- **Visual Schema Design**: Node-based schema editor
|
|
910
|
+
- **Canvas Export**: YAML and Mermaid diagram formats
|
|
911
|
+
- **Obsidian Compatible**: Works with Obsidian Canvas format
|
|
912
|
+
- **FSM Visualization**: State machine and flow diagrams
|
|
913
|
+
- **Bi-directional Sync**: Canvas ↔ Schema round-tripping
|
|
914
|
+
- **Guardian Validation**: Pre-commit lifecycle checks
|
|
915
|
+
|
|
916
|
+
**Status**: ✅ Available (`src/integrations/code-canvas.ts`)
|
|
917
|
+
**CLI**: Use `praxis canvas` commands (coming soon)
|
|
757
918
|
**Documentation**: [docs/guides/canvas.md](./docs/guides/canvas.md)
|
|
758
919
|
|
|
759
920
|
### Svelte + Tauri Runtime
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// src/core/pluresdb/adapter.ts
|
|
2
|
+
var InMemoryPraxisDB = class {
|
|
3
|
+
store = /* @__PURE__ */ new Map();
|
|
4
|
+
watchers = /* @__PURE__ */ new Map();
|
|
5
|
+
async get(key) {
|
|
6
|
+
return this.store.get(key);
|
|
7
|
+
}
|
|
8
|
+
async set(key, value) {
|
|
9
|
+
this.store.set(key, value);
|
|
10
|
+
const keyWatchers = this.watchers.get(key);
|
|
11
|
+
if (keyWatchers) {
|
|
12
|
+
for (const callback of keyWatchers) {
|
|
13
|
+
callback(value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
watch(key, callback) {
|
|
18
|
+
if (!this.watchers.has(key)) {
|
|
19
|
+
this.watchers.set(key, /* @__PURE__ */ new Set());
|
|
20
|
+
}
|
|
21
|
+
const watchers = this.watchers.get(key);
|
|
22
|
+
const wrappedCallback = (val) => callback(val);
|
|
23
|
+
watchers.add(wrappedCallback);
|
|
24
|
+
return () => {
|
|
25
|
+
watchers.delete(wrappedCallback);
|
|
26
|
+
if (watchers.size === 0) {
|
|
27
|
+
this.watchers.delete(key);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get all keys (for testing/debugging)
|
|
33
|
+
*/
|
|
34
|
+
keys() {
|
|
35
|
+
return Array.from(this.store.keys());
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Clear all data (for testing)
|
|
39
|
+
*/
|
|
40
|
+
clear() {
|
|
41
|
+
this.store.clear();
|
|
42
|
+
this.watchers.clear();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
function createInMemoryDB() {
|
|
46
|
+
return new InMemoryPraxisDB();
|
|
47
|
+
}
|
|
48
|
+
var PluresDBPraxisAdapter = class {
|
|
49
|
+
db;
|
|
50
|
+
watchers = /* @__PURE__ */ new Map();
|
|
51
|
+
pollIntervals = /* @__PURE__ */ new Map();
|
|
52
|
+
lastValues = /* @__PURE__ */ new Map();
|
|
53
|
+
pollInterval;
|
|
54
|
+
constructor(config) {
|
|
55
|
+
if ("get" in config && "put" in config) {
|
|
56
|
+
this.db = config;
|
|
57
|
+
this.pollInterval = 1e3;
|
|
58
|
+
} else {
|
|
59
|
+
this.db = config.db;
|
|
60
|
+
this.pollInterval = config.pollInterval ?? 1e3;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async get(key) {
|
|
64
|
+
try {
|
|
65
|
+
const value = await this.db.get(key);
|
|
66
|
+
return value;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async set(key, value) {
|
|
72
|
+
await this.db.put(key, value);
|
|
73
|
+
this.lastValues.set(key, value);
|
|
74
|
+
const keyWatchers = this.watchers.get(key);
|
|
75
|
+
if (keyWatchers) {
|
|
76
|
+
for (const callback of keyWatchers) {
|
|
77
|
+
callback(value);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
watch(key, callback) {
|
|
82
|
+
if (!this.watchers.has(key)) {
|
|
83
|
+
this.watchers.set(key, /* @__PURE__ */ new Set());
|
|
84
|
+
}
|
|
85
|
+
const watchers = this.watchers.get(key);
|
|
86
|
+
const wrappedCallback = (val) => callback(val);
|
|
87
|
+
watchers.add(wrappedCallback);
|
|
88
|
+
if (!this.pollIntervals.has(key)) {
|
|
89
|
+
const interval = setInterval(async () => {
|
|
90
|
+
try {
|
|
91
|
+
const value = await this.db.get(key);
|
|
92
|
+
const lastValue = this.lastValues.get(key);
|
|
93
|
+
if (JSON.stringify(value) !== JSON.stringify(lastValue)) {
|
|
94
|
+
this.lastValues.set(key, value);
|
|
95
|
+
const currentWatchers = this.watchers.get(key);
|
|
96
|
+
if (currentWatchers) {
|
|
97
|
+
for (const cb of currentWatchers) {
|
|
98
|
+
cb(value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch (error) {
|
|
103
|
+
}
|
|
104
|
+
}, this.pollInterval);
|
|
105
|
+
this.pollIntervals.set(key, interval);
|
|
106
|
+
}
|
|
107
|
+
return () => {
|
|
108
|
+
watchers.delete(wrappedCallback);
|
|
109
|
+
if (watchers.size === 0) {
|
|
110
|
+
this.watchers.delete(key);
|
|
111
|
+
const interval = this.pollIntervals.get(key);
|
|
112
|
+
if (interval) {
|
|
113
|
+
clearInterval(interval);
|
|
114
|
+
this.pollIntervals.delete(key);
|
|
115
|
+
}
|
|
116
|
+
this.lastValues.delete(key);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clean up all resources
|
|
122
|
+
*/
|
|
123
|
+
dispose() {
|
|
124
|
+
for (const interval of this.pollIntervals.values()) {
|
|
125
|
+
clearInterval(interval);
|
|
126
|
+
}
|
|
127
|
+
this.pollIntervals.clear();
|
|
128
|
+
this.watchers.clear();
|
|
129
|
+
this.lastValues.clear();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
function createPluresDB(config) {
|
|
133
|
+
return new PluresDBPraxisAdapter(config);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export {
|
|
137
|
+
InMemoryPraxisDB,
|
|
138
|
+
createInMemoryDB,
|
|
139
|
+
PluresDBPraxisAdapter,
|
|
140
|
+
createPluresDB
|
|
141
|
+
};
|