@livestore/cli 0.0.0-snapshot-2ac5fd340c97c9e07fe4c5dc6d31d5132aa6557c.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.
Files changed (80) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/LICENSE +201 -0
  3. package/dist/cli +0 -0
  4. package/dist/cli.d.ts +15 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +22 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/mcp-coach.d.ts +15 -0
  9. package/dist/commands/mcp-coach.d.ts.map +1 -0
  10. package/dist/commands/mcp-coach.js +87 -0
  11. package/dist/commands/mcp-coach.js.map +1 -0
  12. package/dist/commands/mcp-tools.d.ts +41 -0
  13. package/dist/commands/mcp-tools.d.ts.map +1 -0
  14. package/dist/commands/mcp-tools.js +148 -0
  15. package/dist/commands/mcp-tools.js.map +1 -0
  16. package/dist/commands/mcp.d.ts +5 -0
  17. package/dist/commands/mcp.d.ts.map +1 -0
  18. package/dist/commands/mcp.js +67 -0
  19. package/dist/commands/mcp.js.map +1 -0
  20. package/dist/commands/new-project.d.ts +34 -0
  21. package/dist/commands/new-project.d.ts.map +1 -0
  22. package/dist/commands/new-project.js +163 -0
  23. package/dist/commands/new-project.js.map +1 -0
  24. package/dist/mcp-content/architecture.d.ts +2 -0
  25. package/dist/mcp-content/architecture.d.ts.map +1 -0
  26. package/dist/mcp-content/architecture.js +171 -0
  27. package/dist/mcp-content/architecture.js.map +1 -0
  28. package/dist/mcp-content/features.d.ts +2 -0
  29. package/dist/mcp-content/features.d.ts.map +1 -0
  30. package/dist/mcp-content/features.js +177 -0
  31. package/dist/mcp-content/features.js.map +1 -0
  32. package/dist/mcp-content/getting-started.d.ts +2 -0
  33. package/dist/mcp-content/getting-started.d.ts.map +1 -0
  34. package/dist/mcp-content/getting-started.js +405 -0
  35. package/dist/mcp-content/getting-started.js.map +1 -0
  36. package/dist/mcp-content/overview.d.ts +2 -0
  37. package/dist/mcp-content/overview.d.ts.map +1 -0
  38. package/dist/mcp-content/overview.js +120 -0
  39. package/dist/mcp-content/overview.js.map +1 -0
  40. package/dist/mcp-content/schemas/blog.d.ts +2 -0
  41. package/dist/mcp-content/schemas/blog.d.ts.map +1 -0
  42. package/dist/mcp-content/schemas/blog.js +223 -0
  43. package/dist/mcp-content/schemas/blog.js.map +1 -0
  44. package/dist/mcp-content/schemas/ecommerce.d.ts +2 -0
  45. package/dist/mcp-content/schemas/ecommerce.d.ts.map +1 -0
  46. package/dist/mcp-content/schemas/ecommerce.js +436 -0
  47. package/dist/mcp-content/schemas/ecommerce.js.map +1 -0
  48. package/dist/mcp-content/schemas/social.d.ts +2 -0
  49. package/dist/mcp-content/schemas/social.d.ts.map +1 -0
  50. package/dist/mcp-content/schemas/social.js +339 -0
  51. package/dist/mcp-content/schemas/social.js.map +1 -0
  52. package/dist/mcp-content/schemas/todo.d.ts +2 -0
  53. package/dist/mcp-content/schemas/todo.d.ts.map +1 -0
  54. package/dist/mcp-content/schemas/todo.js +172 -0
  55. package/dist/mcp-content/schemas/todo.js.map +1 -0
  56. package/dist/mod.d.ts +2 -0
  57. package/dist/mod.d.ts.map +1 -0
  58. package/dist/mod.js +2 -0
  59. package/dist/mod.js.map +1 -0
  60. package/dist/test-tool.d.ts +2 -0
  61. package/dist/test-tool.d.ts.map +1 -0
  62. package/dist/test-tool.js +57 -0
  63. package/dist/test-tool.js.map +1 -0
  64. package/dist/tsconfig.tsbuildinfo +1 -0
  65. package/package.json +27 -0
  66. package/src/cli.ts +35 -0
  67. package/src/commands/mcp-coach.ts +121 -0
  68. package/src/commands/mcp-tools.ts +169 -0
  69. package/src/commands/mcp.ts +97 -0
  70. package/src/commands/new-project.ts +263 -0
  71. package/src/mcp-content/architecture.ts +170 -0
  72. package/src/mcp-content/features.ts +176 -0
  73. package/src/mcp-content/getting-started.ts +404 -0
  74. package/src/mcp-content/overview.ts +119 -0
  75. package/src/mcp-content/schemas/blog.ts +222 -0
  76. package/src/mcp-content/schemas/ecommerce.ts +435 -0
  77. package/src/mcp-content/schemas/social.ts +338 -0
  78. package/src/mcp-content/schemas/todo.ts +171 -0
  79. package/src/mod.ts +1 -0
  80. package/tsconfig.json +9 -0
@@ -0,0 +1,120 @@
1
+ export const overviewContent = `# LiveStore: Local-First Data Platform
2
+
3
+ LiveStore is a production-ready local-first data platform that combines the immediate responsiveness of local SQLite databases with the collaborative power of real-time synchronization. Built on distributed systems principles from Martin Kleppmann's research, LiveStore enables applications that work seamlessly offline and sync reliably when online.
4
+
5
+ ## Core Philosophy
6
+
7
+ **Local-First Principles**: Your data lives primarily on your device, not in the cloud. Applications respond immediately to user actions without network round-trips, providing the smooth experience users expect from native applications.
8
+
9
+ **Collaborative by Design**: Real-time collaboration isn't an afterthought – it's built into the foundation. Multiple users can work together seamlessly with automatic conflict resolution and eventual consistency guarantees.
10
+
11
+ **Reliability Through Event Sourcing**: All changes are captured as immutable events, providing a complete audit trail and enabling powerful features like undo/redo, time travel debugging, and deterministic testing.
12
+
13
+ ## What Makes LiveStore Different
14
+
15
+ ### 💾 Local SQLite Performance
16
+ - **Sub-millisecond queries** from local SQLite database
17
+ - **Complex joins and aggregations** with full SQL expressiveness
18
+ - **Reactive queries** that automatically update your UI
19
+ - **ACID transactions** for data integrity
20
+
21
+ ### 🌐 Distributed Systems Reliability
22
+ - **Conflict-free synchronization** using CRDT-inspired merge strategies
23
+ - **Causal consistency** with vector clocks and event ordering
24
+ - **Network partition tolerance** – works offline, syncs when online
25
+ - **Eventually consistent** convergence across all replicas
26
+
27
+ ### 🔐 End-to-End Type Safety
28
+ - **Schema-first development** with Effect-based validation
29
+ - **Compile-time query validation** prevents runtime errors
30
+ - **Automatic TypeScript generation** from schema definitions
31
+ - **Runtime safety** with comprehensive input validation
32
+
33
+ ### 🏗️ Framework Agnostic
34
+ - **React, Vue, Solid, Svelte** – use with any frontend framework
35
+ - **Web, Node.js, React Native** – deploy anywhere JavaScript runs
36
+ - **Consistent API** across all platforms and frameworks
37
+
38
+ ## Real-World Use Cases
39
+
40
+ ### 📝 Collaborative Applications
41
+ - **Document editors** with real-time collaboration (Google Docs-style)
42
+ - **Project management** tools with team coordination
43
+ - **Design tools** with multiplayer editing capabilities
44
+ - **Chat applications** with offline message queuing
45
+
46
+ ### 📱 Mobile-First Applications
47
+ - **Field service apps** that work in areas with poor connectivity
48
+ - **Healthcare applications** with sensitive data that must stay local
49
+ - **Educational apps** for students in low-connectivity environments
50
+ - **Financial apps** requiring immediate transaction feedback
51
+
52
+ ### 🏮 Enterprise Applications
53
+ - **CRM systems** with offline sales capability
54
+ - **Inventory management** with real-time stock updates
55
+ - **Customer service** tools with offline case management
56
+ - **Analytics dashboards** with local data caching
57
+
58
+ ## Architecture at a Glance
59
+
60
+ \`\`\`mermaid
61
+ graph TB
62
+ UI[UI Framework] --> Queries[Reactive Queries]
63
+ UI --> Events[Event Dispatch]
64
+
65
+ Events --> EventLog[Event Log]
66
+ EventLog --> Materializers[Materializers]
67
+ Materializers --> SQLite[SQLite Database]
68
+ Queries --> SQLite
69
+
70
+ EventLog --> Sync[Sync Engine]
71
+ Sync --> Network[Network Layer]
72
+ Network --> Server[Sync Server]
73
+
74
+ Server --> OtherClients[Other Clients]
75
+ OtherClients --> Server
76
+ Server --> Network
77
+ \`\`\`
78
+
79
+ 1. **UI Layer**: Framework-specific bindings (React, Vue, etc.)
80
+ 2. **Query Layer**: Reactive SQL queries with automatic UI updates
81
+ 3. **Event Layer**: Immutable event log with schema validation
82
+ 4. **Materialization**: Events applied to SQLite tables via materializers
83
+ 5. **Synchronization**: Conflict-free replication across devices/users
84
+ 6. **Storage**: Local SQLite database for immediate data access
85
+
86
+ ## Key Technical Innovations
87
+
88
+ ### Event-Driven State Management
89
+ Unlike traditional ORMs that hide change tracking, LiveStore makes all state changes explicit through events. This provides:
90
+ - **Deterministic state updates** that can be tested and debugged
91
+ - **Conflict resolution** through event reordering and semantic merging
92
+ - **Time travel** capabilities for debugging and feature development
93
+ - **Audit trails** for compliance and data governance
94
+
95
+ ### Sophisticated Conflict Resolution
96
+ LiveStore handles conflicts intelligently using multiple strategies:
97
+ - **Last-Write-Wins**: Simple timestamp-based resolution
98
+ - **Semantic Merging**: Application-specific conflict resolution logic
99
+ - **Operational Transforms**: For real-time collaborative text editing
100
+ - **CRDT Integration**: Conflict-free data types for specific use cases
101
+
102
+ ### Performance Optimization
103
+ - **Query compilation caching** for repeated queries
104
+ - **Reactive dependency tracking** to minimize unnecessary updates
105
+ - **Incremental synchronization** to reduce network overhead
106
+ - **Background processing** to keep the UI thread responsive
107
+
108
+ ## Production Ready
109
+
110
+ LiveStore is designed for production applications with enterprise-grade requirements:
111
+
112
+ - **Security**: End-to-end encryption, event signatures, access control
113
+ - **Observability**: Distributed tracing, performance monitoring, health checks
114
+ - **Scalability**: Horizontal scaling, connection pooling, data partitioning
115
+ - **Reliability**: Automatic retries, circuit breakers, graceful degradation
116
+
117
+ Whether you're building a simple todo app or a complex collaborative platform, LiveStore provides the foundation for applications that users love – fast, reliable, and always available.
118
+
119
+ **Ready to get started?** Check out our [Getting Started Guide](./getting-started) or explore our [Example Applications](https://github.com/livestorejs/examples).`;
120
+ //# sourceMappingURL=overview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../src/mcp-content/overview.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mKAsHoI,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const blogSchemaContent = "import { Events, makeSchema, Schema, SessionIdSymbol, State } from '@livestore/livestore'\n\n// Content management with collaborative editing capabilities\nexport const tables = {\n posts: State.SQLite.table({\n name: 'posts',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n title: State.SQLite.text(),\n content: State.SQLite.text(), // Consider using JSON for rich text operations\n slug: State.SQLite.text(),\n published: State.SQLite.boolean({ default: false }),\n authorId: State.SQLite.text(),\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n publishedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n version: State.SQLite.integer({ default: 1 }), // For optimistic concurrency\n },\n }),\n \n comments: State.SQLite.table({\n name: 'comments',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n postId: State.SQLite.text(),\n authorId: State.SQLite.text(),\n content: State.SQLite.text(),\n parentId: State.SQLite.text({ nullable: true }), // For threaded comments\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n editedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n },\n }),\n \n authors: State.SQLite.table({\n name: 'authors',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n name: State.SQLite.text(),\n email: State.SQLite.text(),\n bio: State.SQLite.text({ nullable: true }),\n avatarUrl: State.SQLite.text({ nullable: true }),\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n },\n }),\n \n // Track collaborative editing sessions\n editingSessions: State.SQLite.clientDocument({\n name: 'editingSessions',\n schema: Schema.Struct({\n postId: Schema.String,\n authorId: Schema.String,\n lastActivity: Schema.Date,\n cursorPosition: Schema.Number,\n }),\n default: { \n id: SessionIdSymbol, \n value: { postId: '', authorId: '', lastActivity: new Date(), cursorPosition: 0 }\n },\n }),\n}\n\nexport const events = {\n // Post lifecycle events\n postCreated: Events.synced({\n name: 'v1.PostCreated',\n schema: Schema.Struct({\n id: Schema.String,\n title: Schema.String,\n slug: Schema.String,\n authorId: Schema.String,\n createdAt: Schema.Date,\n }),\n }),\n \n postTitleChanged: Events.synced({\n name: 'v1.PostTitleChanged',\n schema: Schema.Struct({\n id: Schema.String,\n title: Schema.String,\n version: Schema.Number, // Optimistic concurrency control\n }),\n }),\n \n postContentChanged: Events.synced({\n name: 'v1.PostContentChanged',\n schema: Schema.Struct({\n id: Schema.String,\n content: Schema.String,\n version: Schema.Number,\n authorId: Schema.String,\n }),\n }),\n \n postPublished: Events.synced({\n name: 'v1.PostPublished',\n schema: Schema.Struct({\n id: Schema.String,\n publishedAt: Schema.Date,\n }),\n }),\n \n postUnpublished: Events.synced({\n name: 'v1.PostUnpublished',\n schema: Schema.Struct({ id: Schema.String }),\n }),\n \n postDeleted: Events.synced({\n name: 'v1.PostDeleted',\n schema: Schema.Struct({\n id: Schema.String,\n deletedAt: Schema.Date,\n }),\n }),\n \n // Comment events\n commentCreated: Events.synced({\n name: 'v1.CommentCreated',\n schema: Schema.Struct({\n id: Schema.String,\n postId: Schema.String,\n authorId: Schema.String,\n content: Schema.String,\n parentId: Schema.NullOr(Schema.String),\n createdAt: Schema.Date,\n }),\n }),\n \n commentEdited: Events.synced({\n name: 'v1.CommentEdited',\n schema: Schema.Struct({\n id: Schema.String,\n content: Schema.String,\n editedAt: Schema.Date,\n }),\n }),\n \n commentDeleted: Events.synced({\n name: 'v1.CommentDeleted',\n schema: Schema.Struct({\n id: Schema.String,\n deletedAt: Schema.Date,\n }),\n }),\n \n // Author events\n authorCreated: Events.synced({\n name: 'v1.AuthorCreated',\n schema: Schema.Struct({\n id: Schema.String,\n name: Schema.String,\n email: Schema.String,\n createdAt: Schema.Date,\n }),\n }),\n \n // Local editing session tracking\n editingSessionUpdated: tables.editingSessions.set,\n}\n\n// Materializers with conflict resolution strategies\nconst materializers = State.SQLite.materializers(events, {\n // Post materializers\n 'v1.PostCreated': ({ id, title, slug, authorId, createdAt }) =>\n tables.posts.insert({ id, title, content: '', slug, authorId, createdAt, version: 1 }),\n \n 'v1.PostTitleChanged': ({ id, title, version }) =>\n // Last-write-wins with version check for optimistic concurrency\n tables.posts.update({ title, version }).where({ id }),\n \n 'v1.PostContentChanged': ({ id, content, version, authorId }) =>\n tables.posts.update({ content, version }).where({ id }),\n \n 'v1.PostPublished': ({ id, publishedAt }) =>\n tables.posts.update({ published: true, publishedAt }).where({ id }),\n \n 'v1.PostUnpublished': ({ id }) =>\n tables.posts.update({ published: false, publishedAt: null }).where({ id }),\n \n 'v1.PostDeleted': ({ id, deletedAt }) =>\n tables.posts.update({ deletedAt }).where({ id }),\n \n // Comment materializers\n 'v1.CommentCreated': ({ id, postId, authorId, content, parentId, createdAt }) =>\n tables.comments.insert({ id, postId, authorId, content, parentId, createdAt }),\n \n 'v1.CommentEdited': ({ id, content, editedAt }) =>\n tables.comments.update({ content, editedAt }).where({ id }),\n \n 'v1.CommentDeleted': ({ id, deletedAt }) =>\n tables.comments.update({ deletedAt }).where({ id }),\n \n // Author materializers\n 'v1.AuthorCreated': ({ id, name, email, createdAt }) =>\n tables.authors.insert({ id, name, email, createdAt }),\n})\n\nconst state = State.SQLite.makeState({ tables, materializers })\n\nexport const schema = makeSchema({ events, state })\n\n// Example queries:\n//\n// // Published posts with author info\n// const publishedPosts$ = queryDb(\n// tables.posts\n// .select()\n// .join(tables.authors, 'authorId', 'id')\n// .where({ published: true, deletedAt: null })\n// .orderBy('publishedAt', 'desc'),\n// { label: 'publishedPosts' }\n// )\n//\n// // Comments for a post (threaded)\n// const postComments$ = (postId: string) => queryDb(\n// tables.comments\n// .select()\n// .join(tables.authors, 'authorId', 'id') \n// .where({ postId, deletedAt: null })\n// .orderBy('createdAt'),\n// { label: `postComments-${postId}` }\n// )";
2
+ //# sourceMappingURL=blog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog.d.ts","sourceRoot":"","sources":["../../../src/mcp-content/schemas/blog.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,w1NA6NzB,CAAA"}
@@ -0,0 +1,223 @@
1
+ export const blogSchemaContent = `import { Events, makeSchema, Schema, SessionIdSymbol, State } from '@livestore/livestore'
2
+
3
+ // Content management with collaborative editing capabilities
4
+ export const tables = {
5
+ posts: State.SQLite.table({
6
+ name: 'posts',
7
+ columns: {
8
+ id: State.SQLite.text({ primaryKey: true }),
9
+ title: State.SQLite.text(),
10
+ content: State.SQLite.text(), // Consider using JSON for rich text operations
11
+ slug: State.SQLite.text(),
12
+ published: State.SQLite.boolean({ default: false }),
13
+ authorId: State.SQLite.text(),
14
+ createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),
15
+ publishedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
16
+ deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
17
+ version: State.SQLite.integer({ default: 1 }), // For optimistic concurrency
18
+ },
19
+ }),
20
+
21
+ comments: State.SQLite.table({
22
+ name: 'comments',
23
+ columns: {
24
+ id: State.SQLite.text({ primaryKey: true }),
25
+ postId: State.SQLite.text(),
26
+ authorId: State.SQLite.text(),
27
+ content: State.SQLite.text(),
28
+ parentId: State.SQLite.text({ nullable: true }), // For threaded comments
29
+ createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),
30
+ editedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
31
+ deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
32
+ },
33
+ }),
34
+
35
+ authors: State.SQLite.table({
36
+ name: 'authors',
37
+ columns: {
38
+ id: State.SQLite.text({ primaryKey: true }),
39
+ name: State.SQLite.text(),
40
+ email: State.SQLite.text(),
41
+ bio: State.SQLite.text({ nullable: true }),
42
+ avatarUrl: State.SQLite.text({ nullable: true }),
43
+ createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),
44
+ },
45
+ }),
46
+
47
+ // Track collaborative editing sessions
48
+ editingSessions: State.SQLite.clientDocument({
49
+ name: 'editingSessions',
50
+ schema: Schema.Struct({
51
+ postId: Schema.String,
52
+ authorId: Schema.String,
53
+ lastActivity: Schema.Date,
54
+ cursorPosition: Schema.Number,
55
+ }),
56
+ default: {
57
+ id: SessionIdSymbol,
58
+ value: { postId: '', authorId: '', lastActivity: new Date(), cursorPosition: 0 }
59
+ },
60
+ }),
61
+ }
62
+
63
+ export const events = {
64
+ // Post lifecycle events
65
+ postCreated: Events.synced({
66
+ name: 'v1.PostCreated',
67
+ schema: Schema.Struct({
68
+ id: Schema.String,
69
+ title: Schema.String,
70
+ slug: Schema.String,
71
+ authorId: Schema.String,
72
+ createdAt: Schema.Date,
73
+ }),
74
+ }),
75
+
76
+ postTitleChanged: Events.synced({
77
+ name: 'v1.PostTitleChanged',
78
+ schema: Schema.Struct({
79
+ id: Schema.String,
80
+ title: Schema.String,
81
+ version: Schema.Number, // Optimistic concurrency control
82
+ }),
83
+ }),
84
+
85
+ postContentChanged: Events.synced({
86
+ name: 'v1.PostContentChanged',
87
+ schema: Schema.Struct({
88
+ id: Schema.String,
89
+ content: Schema.String,
90
+ version: Schema.Number,
91
+ authorId: Schema.String,
92
+ }),
93
+ }),
94
+
95
+ postPublished: Events.synced({
96
+ name: 'v1.PostPublished',
97
+ schema: Schema.Struct({
98
+ id: Schema.String,
99
+ publishedAt: Schema.Date,
100
+ }),
101
+ }),
102
+
103
+ postUnpublished: Events.synced({
104
+ name: 'v1.PostUnpublished',
105
+ schema: Schema.Struct({ id: Schema.String }),
106
+ }),
107
+
108
+ postDeleted: Events.synced({
109
+ name: 'v1.PostDeleted',
110
+ schema: Schema.Struct({
111
+ id: Schema.String,
112
+ deletedAt: Schema.Date,
113
+ }),
114
+ }),
115
+
116
+ // Comment events
117
+ commentCreated: Events.synced({
118
+ name: 'v1.CommentCreated',
119
+ schema: Schema.Struct({
120
+ id: Schema.String,
121
+ postId: Schema.String,
122
+ authorId: Schema.String,
123
+ content: Schema.String,
124
+ parentId: Schema.NullOr(Schema.String),
125
+ createdAt: Schema.Date,
126
+ }),
127
+ }),
128
+
129
+ commentEdited: Events.synced({
130
+ name: 'v1.CommentEdited',
131
+ schema: Schema.Struct({
132
+ id: Schema.String,
133
+ content: Schema.String,
134
+ editedAt: Schema.Date,
135
+ }),
136
+ }),
137
+
138
+ commentDeleted: Events.synced({
139
+ name: 'v1.CommentDeleted',
140
+ schema: Schema.Struct({
141
+ id: Schema.String,
142
+ deletedAt: Schema.Date,
143
+ }),
144
+ }),
145
+
146
+ // Author events
147
+ authorCreated: Events.synced({
148
+ name: 'v1.AuthorCreated',
149
+ schema: Schema.Struct({
150
+ id: Schema.String,
151
+ name: Schema.String,
152
+ email: Schema.String,
153
+ createdAt: Schema.Date,
154
+ }),
155
+ }),
156
+
157
+ // Local editing session tracking
158
+ editingSessionUpdated: tables.editingSessions.set,
159
+ }
160
+
161
+ // Materializers with conflict resolution strategies
162
+ const materializers = State.SQLite.materializers(events, {
163
+ // Post materializers
164
+ 'v1.PostCreated': ({ id, title, slug, authorId, createdAt }) =>
165
+ tables.posts.insert({ id, title, content: '', slug, authorId, createdAt, version: 1 }),
166
+
167
+ 'v1.PostTitleChanged': ({ id, title, version }) =>
168
+ // Last-write-wins with version check for optimistic concurrency
169
+ tables.posts.update({ title, version }).where({ id }),
170
+
171
+ 'v1.PostContentChanged': ({ id, content, version, authorId }) =>
172
+ tables.posts.update({ content, version }).where({ id }),
173
+
174
+ 'v1.PostPublished': ({ id, publishedAt }) =>
175
+ tables.posts.update({ published: true, publishedAt }).where({ id }),
176
+
177
+ 'v1.PostUnpublished': ({ id }) =>
178
+ tables.posts.update({ published: false, publishedAt: null }).where({ id }),
179
+
180
+ 'v1.PostDeleted': ({ id, deletedAt }) =>
181
+ tables.posts.update({ deletedAt }).where({ id }),
182
+
183
+ // Comment materializers
184
+ 'v1.CommentCreated': ({ id, postId, authorId, content, parentId, createdAt }) =>
185
+ tables.comments.insert({ id, postId, authorId, content, parentId, createdAt }),
186
+
187
+ 'v1.CommentEdited': ({ id, content, editedAt }) =>
188
+ tables.comments.update({ content, editedAt }).where({ id }),
189
+
190
+ 'v1.CommentDeleted': ({ id, deletedAt }) =>
191
+ tables.comments.update({ deletedAt }).where({ id }),
192
+
193
+ // Author materializers
194
+ 'v1.AuthorCreated': ({ id, name, email, createdAt }) =>
195
+ tables.authors.insert({ id, name, email, createdAt }),
196
+ })
197
+
198
+ const state = State.SQLite.makeState({ tables, materializers })
199
+
200
+ export const schema = makeSchema({ events, state })
201
+
202
+ // Example queries:
203
+ //
204
+ // // Published posts with author info
205
+ // const publishedPosts$ = queryDb(
206
+ // tables.posts
207
+ // .select()
208
+ // .join(tables.authors, 'authorId', 'id')
209
+ // .where({ published: true, deletedAt: null })
210
+ // .orderBy('publishedAt', 'desc'),
211
+ // { label: 'publishedPosts' }
212
+ // )
213
+ //
214
+ // // Comments for a post (threaded)
215
+ // const postComments$ = (postId: string) => queryDb(
216
+ // tables.comments
217
+ // .select()
218
+ // .join(tables.authors, 'authorId', 'id')
219
+ // .where({ postId, deletedAt: null })
220
+ // .orderBy('createdAt'),
221
+ // { label: \`postComments-\${postId}\` }
222
+ // )`;
223
+ //# sourceMappingURL=blog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog.js","sourceRoot":"","sources":["../../../src/mcp-content/schemas/blog.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6N5B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const ecommerceSchemaContent = "import { Events, makeSchema, Schema, SessionIdSymbol, State } from '@livestore/livestore'\n\n// E-commerce with inventory management and order processing\nexport const tables = {\n products: State.SQLite.table({\n name: 'products',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n sku: State.SQLite.text(),\n name: State.SQLite.text(),\n description: State.SQLite.text(),\n price: State.SQLite.integer(), // Store as cents to avoid floating point issues\n currency: State.SQLite.text({ default: 'USD' }),\n stock: State.SQLite.integer({ default: 0 }),\n reservedStock: State.SQLite.integer({ default: 0 }), // For pending orders\n isActive: State.SQLite.boolean({ default: true }),\n weight: State.SQLite.real({ nullable: true }), // For shipping calculations\n dimensions: State.SQLite.text({ nullable: true }), // JSON: {width, height, depth}\n imageUrls: State.SQLite.text({ nullable: true }), // JSON array\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n updatedAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n },\n }),\n \n categories: State.SQLite.table({\n name: 'categories',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n name: State.SQLite.text(),\n slug: State.SQLite.text(),\n parentId: State.SQLite.text({ nullable: true }), // For hierarchical categories\n description: State.SQLite.text({ nullable: true }),\n imageUrl: State.SQLite.text({ nullable: true }),\n sortOrder: State.SQLite.integer({ default: 0 }),\n isActive: State.SQLite.boolean({ default: true }),\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n },\n }),\n \n productCategories: State.SQLite.table({\n name: 'product_categories',\n columns: {\n productId: State.SQLite.text(),\n categoryId: State.SQLite.text(),\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n },\n }),\n \n customers: State.SQLite.table({\n name: 'customers',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n email: State.SQLite.text(),\n firstName: State.SQLite.text({ nullable: true }),\n lastName: State.SQLite.text({ nullable: true }),\n phone: State.SQLite.text({ nullable: true }),\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n lastOrderAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n },\n }),\n \n addresses: State.SQLite.table({\n name: 'addresses',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n customerId: State.SQLite.text(),\n type: State.SQLite.text({ default: 'shipping' }), // shipping, billing\n firstName: State.SQLite.text(),\n lastName: State.SQLite.text(),\n company: State.SQLite.text({ nullable: true }),\n address1: State.SQLite.text(),\n address2: State.SQLite.text({ nullable: true }),\n city: State.SQLite.text(),\n state: State.SQLite.text(),\n country: State.SQLite.text(),\n postalCode: State.SQLite.text(),\n isDefault: State.SQLite.boolean({ default: false }),\n },\n }),\n \n orders: State.SQLite.table({\n name: 'orders',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n orderNumber: State.SQLite.text(), // Human-readable order number\n customerId: State.SQLite.text(),\n status: State.SQLite.text({ default: 'draft' }), // draft, pending, paid, processing, shipped, delivered, cancelled\n paymentStatus: State.SQLite.text({ default: 'pending' }), // pending, paid, failed, refunded\n fulfillmentStatus: State.SQLite.text({ default: 'unfulfilled' }), // unfulfilled, partial, fulfilled\n \n subtotal: State.SQLite.integer(), // In cents\n taxAmount: State.SQLite.integer({ default: 0 }),\n shippingAmount: State.SQLite.integer({ default: 0 }),\n discountAmount: State.SQLite.integer({ default: 0 }),\n total: State.SQLite.integer(),\n currency: State.SQLite.text({ default: 'USD' }),\n \n shippingAddress: State.SQLite.text(), // JSON\n billingAddress: State.SQLite.text(), // JSON\n \n notes: State.SQLite.text({ nullable: true }),\n \n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n updatedAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n cancelledAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n shippedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n deliveredAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),\n },\n }),\n \n orderItems: State.SQLite.table({\n name: 'order_items',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n orderId: State.SQLite.text(),\n productId: State.SQLite.text(),\n variantId: State.SQLite.text({ nullable: true }),\n sku: State.SQLite.text(), // Snapshot at time of order\n name: State.SQLite.text(), // Product name at time of order\n quantity: State.SQLite.integer(),\n unitPrice: State.SQLite.integer(), // Price per unit in cents\n totalPrice: State.SQLite.integer(), // quantity * unitPrice\n fulfillmentStatus: State.SQLite.text({ default: 'unfulfilled' }),\n },\n }),\n \n // Inventory tracking with event sourcing\n inventoryEvents: State.SQLite.table({\n name: 'inventory_events',\n columns: {\n id: State.SQLite.text({ primaryKey: true }),\n productId: State.SQLite.text(),\n type: State.SQLite.text(), // 'adjustment', 'sale', 'return', 'damage', 'restock'\n quantity: State.SQLite.integer(), // Can be positive or negative\n reason: State.SQLite.text({ nullable: true }),\n referenceId: State.SQLite.text({ nullable: true }), // Order ID, adjustment ID, etc.\n createdAt: State.SQLite.integer({ schema: Schema.DateFromNumber }),\n },\n }),\n \n // Shopping cart (client-side state)\n cart: State.SQLite.clientDocument({\n name: 'cart',\n schema: Schema.Struct({\n items: Schema.Array(Schema.Struct({\n productId: Schema.String,\n quantity: Schema.Number,\n addedAt: Schema.Date,\n })),\n discountCode: Schema.NullOr(Schema.String),\n notes: Schema.String,\n }),\n default: { \n id: SessionIdSymbol, \n value: { items: [], discountCode: null, notes: '' }\n },\n }),\n}\n\nexport const events = {\n // Product management\n productCreated: Events.synced({\n name: 'v1.ProductCreated',\n schema: Schema.Struct({\n id: Schema.String,\n sku: Schema.String,\n name: Schema.String,\n description: Schema.String,\n price: Schema.Number, // In cents\n currency: Schema.String,\n createdAt: Schema.Date,\n }),\n }),\n \n productUpdated: Events.synced({\n name: 'v1.ProductUpdated',\n schema: Schema.Struct({\n id: Schema.String,\n name: Schema.NullOr(Schema.String),\n description: Schema.NullOr(Schema.String),\n price: Schema.NullOr(Schema.Number),\n updatedAt: Schema.Date,\n }),\n }),\n \n productStockAdjusted: Events.synced({\n name: 'v1.ProductStockAdjusted',\n schema: Schema.Struct({\n productId: Schema.String,\n adjustment: Schema.Number, // Can be positive or negative\n reason: Schema.String,\n referenceId: Schema.NullOr(Schema.String),\n createdAt: Schema.Date,\n }),\n }),\n \n productDeactivated: Events.synced({\n name: 'v1.ProductDeactivated',\n schema: Schema.Struct({ id: Schema.String }),\n }),\n \n // Customer management\n customerCreated: Events.synced({\n name: 'v1.CustomerCreated',\n schema: Schema.Struct({\n id: Schema.String,\n email: Schema.String,\n firstName: Schema.NullOr(Schema.String),\n lastName: Schema.NullOr(Schema.String),\n createdAt: Schema.Date,\n }),\n }),\n \n // Order lifecycle with state machine\n orderCreated: Events.synced({\n name: 'v1.OrderCreated',\n schema: Schema.Struct({\n id: Schema.String,\n orderNumber: Schema.String,\n customerId: Schema.String,\n items: Schema.Array(Schema.Struct({\n productId: Schema.String,\n sku: Schema.String,\n name: Schema.String,\n quantity: Schema.Number,\n unitPrice: Schema.Number,\n })),\n subtotal: Schema.Number,\n total: Schema.Number,\n shippingAddress: Schema.Object,\n billingAddress: Schema.Object,\n createdAt: Schema.Date,\n }),\n }),\n \n orderPaymentReceived: Events.synced({\n name: 'v1.OrderPaymentReceived',\n schema: Schema.Struct({\n orderId: Schema.String,\n amount: Schema.Number,\n paymentMethod: Schema.String,\n transactionId: Schema.String,\n paidAt: Schema.Date,\n }),\n }),\n \n orderShipped: Events.synced({\n name: 'v1.OrderShipped',\n schema: Schema.Struct({\n orderId: Schema.String,\n trackingNumber: Schema.NullOr(Schema.String),\n carrier: Schema.NullOr(Schema.String),\n shippedAt: Schema.Date,\n }),\n }),\n \n orderDelivered: Events.synced({\n name: 'v1.OrderDelivered',\n schema: Schema.Struct({\n orderId: Schema.String,\n deliveredAt: Schema.Date,\n }),\n }),\n \n orderCancelled: Events.synced({\n name: 'v1.OrderCancelled',\n schema: Schema.Struct({\n orderId: Schema.String,\n reason: Schema.String,\n cancelledAt: Schema.Date,\n }),\n }),\n \n // Cart management (local)\n cartUpdated: tables.cart.set,\n}\n\n// Materializers with business logic and constraints\nconst materializers = State.SQLite.materializers(events, {\n // Product materializers\n 'v1.ProductCreated': ({ id, sku, name, description, price, currency, createdAt }) =>\n tables.products.insert({ id, sku, name, description, price, currency, createdAt, updatedAt: createdAt }),\n \n 'v1.ProductUpdated': ({ id, name, description, price, updatedAt }) =>\n tables.products.update({ \n name: name ?? undefined,\n description: description ?? undefined, \n price: price ?? undefined,\n updatedAt \n }).where({ id }),\n \n 'v1.ProductStockAdjusted': ({ productId, adjustment, reason, referenceId, createdAt }) => [\n // Record the inventory event\n tables.inventoryEvents.insert({ \n id: crypto.randomUUID(),\n productId, \n type: 'adjustment',\n quantity: adjustment, \n reason, \n referenceId, \n createdAt \n }),\n // Update product stock (eventually consistent)\n tables.products.update({ \n stock: Math.max(0, tables.products.select('stock').where({ id: productId }).scalar() + adjustment),\n updatedAt: createdAt\n }).where({ id: productId }),\n ],\n \n 'v1.ProductDeactivated': ({ id }) =>\n tables.products.update({ isActive: false }).where({ id }),\n \n // Customer materializers\n 'v1.CustomerCreated': ({ id, email, firstName, lastName, createdAt }) =>\n tables.customers.insert({ id, email, firstName, lastName, createdAt }),\n \n // Order materializers with inventory reservation\n 'v1.OrderCreated': ({ id, orderNumber, customerId, items, subtotal, total, shippingAddress, billingAddress, createdAt }) => [\n // Create the order\n tables.orders.insert({ \n id, \n orderNumber, \n customerId, \n status: 'pending',\n subtotal, \n total, \n shippingAddress: JSON.stringify(shippingAddress),\n billingAddress: JSON.stringify(billingAddress),\n createdAt, \n updatedAt: createdAt \n }),\n // Create order items and reserve inventory\n ...items.flatMap(item => [\n tables.orderItems.insert({ \n id: crypto.randomUUID(),\n orderId: id,\n productId: item.productId,\n sku: item.sku,\n name: item.name,\n quantity: item.quantity,\n unitPrice: item.unitPrice,\n totalPrice: item.quantity * item.unitPrice,\n }),\n // Reserve stock\n tables.products.update({ \n reservedStock: tables.products.select('reservedStock').where({ id: item.productId }).scalar() + item.quantity\n }).where({ id: item.productId }),\n ]),\n ],\n \n 'v1.OrderPaymentReceived': ({ orderId, amount, paymentMethod, transactionId, paidAt }) =>\n tables.orders.update({ \n status: 'paid', \n paymentStatus: 'paid',\n updatedAt: paidAt \n }).where({ id: orderId }),\n \n 'v1.OrderShipped': ({ orderId, trackingNumber, carrier, shippedAt }) => [\n tables.orders.update({ \n status: 'shipped',\n fulfillmentStatus: 'fulfilled',\n shippedAt,\n updatedAt: shippedAt \n }).where({ id: orderId }),\n // Convert reserved stock to actual stock reduction\n ...tables.orderItems.select().where({ orderId }).map(item => \n tables.products.update({ \n stock: tables.products.select('stock').where({ id: item.productId }).scalar() - item.quantity,\n reservedStock: tables.products.select('reservedStock').where({ id: item.productId }).scalar() - item.quantity\n }).where({ id: item.productId })\n ),\n ],\n \n 'v1.OrderDelivered': ({ orderId, deliveredAt }) =>\n tables.orders.update({ \n status: 'delivered',\n deliveredAt,\n updatedAt: deliveredAt \n }).where({ id: orderId }),\n \n 'v1.OrderCancelled': ({ orderId, reason, cancelledAt }) => [\n tables.orders.update({ \n status: 'cancelled',\n cancelledAt,\n notes: reason,\n updatedAt: cancelledAt \n }).where({ id: orderId }),\n // Release reserved inventory\n ...tables.orderItems.select().where({ orderId }).map(item => \n tables.products.update({ \n reservedStock: Math.max(0, tables.products.select('reservedStock').where({ id: item.productId }).scalar() - item.quantity)\n }).where({ id: item.productId })\n ),\n ],\n})\n\nconst state = State.SQLite.makeState({ tables, materializers })\n\nexport const schema = makeSchema({ events, state })\n\n// Example queries for business intelligence:\n//\n// // Available products with real-time stock\n// const availableProducts$ = queryDb(\n// tables.products\n// .select()\n// .where({ isActive: true, deletedAt: null })\n// .having(tables.products.column('stock').minus(tables.products.column('reservedStock')).gt(0))\n// .orderBy('name'),\n// { label: 'availableProducts' }\n// )\n//\n// // Orders requiring fulfillment\n// const pendingOrders$ = queryDb(\n// tables.orders\n// .select()\n// .join(tables.customers, 'customerId', 'id')\n// .where({ \n// 'orders.status': 'paid',\n// 'orders.fulfillmentStatus': 'unfulfilled'\n// })\n// .orderBy('orders.createdAt'),\n// { label: 'pendingOrders' }\n// )\n//\n// // Low stock alerts\n// const lowStockProducts$ = queryDb(\n// tables.products\n// .select()\n// .where({ isActive: true })\n// .having(tables.products.column('stock').minus(tables.products.column('reservedStock')).lt(10))\n// .orderBy('stock'),\n// { label: 'lowStockProducts' }\n// )";
2
+ //# sourceMappingURL=ecommerce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecommerce.d.ts","sourceRoot":"","sources":["../../../src/mcp-content/schemas/ecommerce.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,y+dAkb9B,CAAA"}