@statezero/core 0.1.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 (89) hide show
  1. package/dist/adaptors/react/composables.d.ts +1 -0
  2. package/dist/adaptors/react/composables.js +4 -0
  3. package/dist/adaptors/react/index.d.ts +1 -0
  4. package/dist/adaptors/react/index.js +1 -0
  5. package/dist/adaptors/vue/composables.d.ts +2 -0
  6. package/dist/adaptors/vue/composables.js +36 -0
  7. package/dist/adaptors/vue/index.d.ts +2 -0
  8. package/dist/adaptors/vue/index.js +2 -0
  9. package/dist/adaptors/vue/reactivity.d.ts +18 -0
  10. package/dist/adaptors/vue/reactivity.js +125 -0
  11. package/dist/cli/commands/syncModels.d.ts +132 -0
  12. package/dist/cli/commands/syncModels.js +1040 -0
  13. package/dist/cli/configFileLoader.d.ts +10 -0
  14. package/dist/cli/configFileLoader.js +85 -0
  15. package/dist/cli/index.d.ts +2 -0
  16. package/dist/cli/index.js +14 -0
  17. package/dist/config.d.ts +52 -0
  18. package/dist/config.js +242 -0
  19. package/dist/core/eventReceivers.d.ts +179 -0
  20. package/dist/core/eventReceivers.js +210 -0
  21. package/dist/core/utils.d.ts +8 -0
  22. package/dist/core/utils.js +62 -0
  23. package/dist/filtering/localFiltering.d.ts +116 -0
  24. package/dist/filtering/localFiltering.js +834 -0
  25. package/dist/flavours/django/dates.d.ts +33 -0
  26. package/dist/flavours/django/dates.js +99 -0
  27. package/dist/flavours/django/errors.d.ts +138 -0
  28. package/dist/flavours/django/errors.js +187 -0
  29. package/dist/flavours/django/f.d.ts +6 -0
  30. package/dist/flavours/django/f.js +91 -0
  31. package/dist/flavours/django/files.d.ts +76 -0
  32. package/dist/flavours/django/files.js +338 -0
  33. package/dist/flavours/django/makeApiCall.d.ts +20 -0
  34. package/dist/flavours/django/makeApiCall.js +169 -0
  35. package/dist/flavours/django/manager.d.ts +197 -0
  36. package/dist/flavours/django/manager.js +222 -0
  37. package/dist/flavours/django/model.d.ts +112 -0
  38. package/dist/flavours/django/model.js +253 -0
  39. package/dist/flavours/django/operationFactory.d.ts +65 -0
  40. package/dist/flavours/django/operationFactory.js +216 -0
  41. package/dist/flavours/django/q.d.ts +70 -0
  42. package/dist/flavours/django/q.js +43 -0
  43. package/dist/flavours/django/queryExecutor.d.ts +131 -0
  44. package/dist/flavours/django/queryExecutor.js +468 -0
  45. package/dist/flavours/django/querySet.d.ts +412 -0
  46. package/dist/flavours/django/querySet.js +601 -0
  47. package/dist/flavours/django/tempPk.d.ts +19 -0
  48. package/dist/flavours/django/tempPk.js +48 -0
  49. package/dist/flavours/django/utils.d.ts +19 -0
  50. package/dist/flavours/django/utils.js +29 -0
  51. package/dist/index.d.ts +38 -0
  52. package/dist/index.js +38 -0
  53. package/dist/react-entry.d.ts +2 -0
  54. package/dist/react-entry.js +2 -0
  55. package/dist/reactiveAdaptor.d.ts +24 -0
  56. package/dist/reactiveAdaptor.js +38 -0
  57. package/dist/setup.d.ts +15 -0
  58. package/dist/setup.js +22 -0
  59. package/dist/syncEngine/cache/cache.d.ts +75 -0
  60. package/dist/syncEngine/cache/cache.js +341 -0
  61. package/dist/syncEngine/metrics/metricOptCalcs.d.ts +79 -0
  62. package/dist/syncEngine/metrics/metricOptCalcs.js +284 -0
  63. package/dist/syncEngine/registries/metricRegistry.d.ts +53 -0
  64. package/dist/syncEngine/registries/metricRegistry.js +162 -0
  65. package/dist/syncEngine/registries/modelStoreRegistry.d.ts +11 -0
  66. package/dist/syncEngine/registries/modelStoreRegistry.js +56 -0
  67. package/dist/syncEngine/registries/querysetStoreRegistry.d.ts +55 -0
  68. package/dist/syncEngine/registries/querysetStoreRegistry.js +244 -0
  69. package/dist/syncEngine/stores/metricStore.d.ts +55 -0
  70. package/dist/syncEngine/stores/metricStore.js +222 -0
  71. package/dist/syncEngine/stores/modelStore.d.ts +40 -0
  72. package/dist/syncEngine/stores/modelStore.js +405 -0
  73. package/dist/syncEngine/stores/operation.d.ts +99 -0
  74. package/dist/syncEngine/stores/operation.js +224 -0
  75. package/dist/syncEngine/stores/operationEventHandlers.d.ts +8 -0
  76. package/dist/syncEngine/stores/operationEventHandlers.js +239 -0
  77. package/dist/syncEngine/stores/querysetStore.d.ts +32 -0
  78. package/dist/syncEngine/stores/querysetStore.js +200 -0
  79. package/dist/syncEngine/stores/reactivity.d.ts +3 -0
  80. package/dist/syncEngine/stores/reactivity.js +4 -0
  81. package/dist/syncEngine/stores/utils.d.ts +14 -0
  82. package/dist/syncEngine/stores/utils.js +32 -0
  83. package/dist/syncEngine/sync.d.ts +32 -0
  84. package/dist/syncEngine/sync.js +169 -0
  85. package/dist/vue-entry.d.ts +6 -0
  86. package/dist/vue-entry.js +2 -0
  87. package/license.md +116 -0
  88. package/package.json +123 -0
  89. package/readme.md +222 -0
package/package.json ADDED
@@ -0,0 +1,123 @@
1
+ {
2
+ "name": "@statezero/core",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "module": "ESNext",
6
+ "description": "The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "statezero": "dist/cli/index.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.js"
16
+ },
17
+ "./cli": {
18
+ "import": "./dist/cli/index.js",
19
+ "require": "./dist/cli/index.js"
20
+ },
21
+ "./react": {
22
+ "import": "./dist/react-entry.js",
23
+ "require": "./dist/react-entry.js"
24
+ },
25
+ "./vue": {
26
+ "import": "./dist/vue-entry.js",
27
+ "require": "./dist/vue-entry.js"
28
+ }
29
+ },
30
+ "scripts": {
31
+ "test": "vitest run --config=vitest.base.config.ts",
32
+ "test:e2e": "vitest run --config=vitest.sequential.config.ts tests/e2e",
33
+ "generate:test-apps": "ts-node scripts/generate-test-apps.js",
34
+ "test:adaptors": "playwright test tests/adaptors",
35
+ "test:coverage": "vitest run --coverage",
36
+ "build": "tsc",
37
+ "parse-queries": "node scripts/perfect-query-parser.js",
38
+ "sync-models": "node src/cli/index.js sync-models",
39
+ "sync-models:dev": "npx cross-env NODE_ENV=test npm run sync-models",
40
+ "clean": "npx rimraf dist",
41
+ "prepare": "npm run clean && npm run build",
42
+ "prepublishOnly": "npm run clean && npm run build"
43
+ },
44
+ "keywords": [
45
+ "typescript",
46
+ "orm",
47
+ "backend",
48
+ "frontend",
49
+ "database",
50
+ "sql",
51
+ "django",
52
+ "sqlalchemy",
53
+ "react",
54
+ "vue",
55
+ "svelte"
56
+ ],
57
+ "author": "Robert Herring <robert.herring@resipilot.com>",
58
+ "license": "SEE LICENSE IN LICENSE",
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/state-zero/statezero-client.git"
62
+ },
63
+ "files": [
64
+ "dist",
65
+ "LICENSE",
66
+ "README.md"
67
+ ],
68
+ "homepage": "https://www.statezero.dev",
69
+ "dependencies": {
70
+ "axios": "^1.7.9",
71
+ "cli-progress": "^3.12.0",
72
+ "cosmiconfig": "^9.0.0",
73
+ "cosmiconfig-typescript-loader": "^6.1.0",
74
+ "date-fns": "^4.1.0",
75
+ "dotenv": "^16.4.7",
76
+ "fs-extra": "^11.3.0",
77
+ "handlebars": "^4.7.8",
78
+ "idb": "^8.0.2",
79
+ "inquirer": "^12.4.2",
80
+ "lodash-es": "^4.17.21",
81
+ "luxon": "^3.6.1",
82
+ "mathjs": "^14.4.0",
83
+ "mitt": "^3.0.1",
84
+ "mobx": "^6.13.7",
85
+ "mobx-utils": "^6.1.0",
86
+ "object-hash": "^3.0.0",
87
+ "openapi-typescript": "^6.7.1",
88
+ "p-queue": "^8.1.0",
89
+ "pusher-js": "^8.4.0",
90
+ "rfdc": "^1.4.1",
91
+ "sift": "^17.1.3",
92
+ "superjson": "^2.2.2",
93
+ "uuid": "^11.1.0",
94
+ "yargs": "^17.7.2",
95
+ "zod": "^3.24.2"
96
+ },
97
+ "devDependencies": {
98
+ "@playwright/test": "^1.50.1",
99
+ "@types/cli-progress": "^3.11.6",
100
+ "@types/lodash-es": "^4.17.12",
101
+ "@types/node": "^22.13.1",
102
+ "@types/react": "^18.3.18",
103
+ "@types/yargs": "^17.0.32",
104
+ "@vitest/coverage-v8": "^3.0.5",
105
+ "fake-indexeddb": "^6.0.0",
106
+ "fast-glob": "^3.3.3",
107
+ "react": "^18.2.0",
108
+ "rimraf": "^5.0.5",
109
+ "ts-node": "^10.9.2",
110
+ "typescript": "^5.7.3",
111
+ "vitest": "^3.0.5",
112
+ "vue": "^3.2.0"
113
+ },
114
+ "publishConfig": {
115
+ "access": "restricted"
116
+ },
117
+ "bugs": {
118
+ "url": "https://github.com/state-zero/statezero-client/issues"
119
+ },
120
+ "directories": {
121
+ "test": "tests"
122
+ }
123
+ }
package/readme.md ADDED
@@ -0,0 +1,222 @@
1
+ # StateZero
2
+
3
+ **The Real-Time Django to JavaScript Data Bridge**
4
+
5
+ Connect your Django backend to React/Vue frontends with 90% less code. No repetitive serializers, views, or tight coupling.
6
+
7
+ ## Why StateZero?
8
+
9
+ **The Problem:** Building modern web apps means writing the same CRUD logic three times - Django models, REST API serializers/views, and frontend data fetching. This creates:
10
+
11
+ - 80% of app complexity in data shuttling
12
+ - 50% of your codebase devoted to API glue
13
+ - Hundreds of hours maintaining sync between frontend and backend
14
+
15
+ **The Solution:** StateZero eliminates the API layer entirely. Write Django models once, query them directly from JavaScript with the same ORM syntax you already know.
16
+
17
+ ## Features
18
+
19
+ ✨ **Django ORM Syntax in JavaScript** - Use `.filter()`, `.exclude()`, `.orderBy()` exactly like Django
20
+ ⚡ **Real-Time Updates** - UI automatically updates when backend data changes
21
+ 🔒 **Django Permissions** - Your existing permission classes work on the frontend
22
+ 📝 **Auto-Generated TypeScript** - Perfect type safety from your Django models
23
+ 🚀 **Optimistic Updates** - UI feels instant, syncs in background
24
+ 🔗 **Deep Relationships** - Traverse foreign keys naturally: `todo.category.name`
25
+
26
+ ## Quick Example
27
+
28
+ ### 1. Register Your Django Model
29
+
30
+ ```python
31
+ # todos/crud.py
32
+ from statezero.adaptors.django.config import registry
33
+ from .models import Todo
34
+
35
+ registry.register(Todo)
36
+ ```
37
+
38
+ ### 2. Query From JavaScript Like Django
39
+
40
+ ```javascript
41
+ // Get all incomplete todos, ordered by priority
42
+ const todos = Todo.objects
43
+ .filter({ is_completed: false })
44
+ .orderBy("-priority", "created_at");
45
+
46
+ // Complex queries with relationships
47
+ const urgentWorkTodos = Todo.objects.filter({
48
+ priority: "high",
49
+ category__name: "Work",
50
+ due_date__lt: "2024-12-31",
51
+ });
52
+
53
+ // Django-style field lookups
54
+ const searchResults = Todo.objects.filter({
55
+ title__icontains: "meeting",
56
+ created_by__email__endswith: "@company.com",
57
+ });
58
+ ```
59
+
60
+ ### 3. Real-Time Updates in One Line
61
+
62
+ ```vue
63
+ <script setup>
64
+ import { useQueryset } from "@statezero/core/vue";
65
+
66
+ // This list automatically updates when todos change
67
+ const todos = useQueryset(() => Todo.objects.filter({ is_completed: false }));
68
+ </script>
69
+
70
+ <template>
71
+ <div v-for="todo in todos.fetch({ limit: 10 })" :key="todo.id">
72
+ {{ todo.title }}
73
+ </div>
74
+ </template>
75
+ ```
76
+
77
+ ## The Magic: Optimistic vs Confirmed
78
+
79
+ ### Optimistic (Instant UI)
80
+
81
+ ```javascript
82
+ // UI updates immediately, syncs later
83
+ const newTodo = Todo.objects.create({
84
+ title: "Buy groceries",
85
+ priority: "medium",
86
+ });
87
+
88
+ // Edit optimistically
89
+ todo.title = "Buy organic groceries";
90
+ todo.save(); // UI updates instantly
91
+
92
+ // Delete optimistically
93
+ todo.delete(); // Gone from UI immediately
94
+ ```
95
+
96
+ ### Confirmed (Wait for Server)
97
+
98
+ ```javascript
99
+ // Wait for server confirmation
100
+ const confirmedTodo = await Todo.objects.create({
101
+ title: "Important meeting",
102
+ });
103
+
104
+ // Wait for update confirmation
105
+ await todo.save();
106
+
107
+ // Wait for deletion confirmation
108
+ await todo.delete();
109
+ ```
110
+
111
+ ## Advanced Django ORM Features
112
+
113
+ ### Complex Filtering with Q Objects
114
+
115
+ ```javascript
116
+ import { Q } from "@statezero/core";
117
+
118
+ // Multiple OR conditions
119
+ const urgentTodos = Todo.objects.filter({
120
+ Q: [Q("OR", { priority: "high" }, { due_date__lt: "tomorrow" })],
121
+ });
122
+
123
+ // Nested conditions
124
+ const myImportantTodos = Todo.objects.filter({
125
+ Q: [
126
+ Q(
127
+ "AND",
128
+ { assigned_to: currentUser.id },
129
+ Q("OR", { priority: "high" }, { is_flagged: true })
130
+ ),
131
+ ],
132
+ });
133
+ ```
134
+
135
+ ### Aggregation & F Expressions
136
+
137
+ ```javascript
138
+ import { F } from "@statezero/core";
139
+
140
+ // Count, sum, average like Django
141
+ const todoCount = await Todo.objects.count();
142
+ const avgPriority = await Todo.objects.avg("priority_score");
143
+
144
+ // Database-level calculations
145
+ await Product.objects.update({
146
+ view_count: F("view_count + 1"),
147
+ popularity: F("likes * 2 + shares"),
148
+ });
149
+ ```
150
+
151
+ ### Get or Create
152
+
153
+ ```javascript
154
+ // Just like Django's get_or_create
155
+ const [todo, created] = await Todo.objects.getOrCreate(
156
+ { title: "Daily standup" },
157
+ { defaults: { priority: "medium", category: workCategory } }
158
+ );
159
+ ```
160
+
161
+ ### Relationship Traversal
162
+
163
+ ```javascript
164
+ // Access related objects naturally
165
+ const todo = await Todo.objects.get({ id: 1 });
166
+ console.log(todo.category.name); // Foreign key
167
+ console.log(todo.created_by.username); // Another FK
168
+ console.log(todo.comments.length); // Reverse FK
169
+
170
+ // Filter by relationships
171
+ const workTodos = Todo.objects.filter({
172
+ category__name: "Work",
173
+ assigned_to__department__name: "Engineering",
174
+ });
175
+ ```
176
+
177
+ ## Installation
178
+
179
+ ### Backend
180
+
181
+ ```bash
182
+ pip install git+https://github.com/state-zero/statezero
183
+ pip install django-cors-headers pusher
184
+ ```
185
+
186
+ ### Frontend
187
+
188
+ ```bash
189
+ npm install https://github.com/state-zero/statezero-client
190
+ ```
191
+
192
+ ### Generate TypeScript Models
193
+
194
+ ```bash
195
+ npx statezero sync-models
196
+ ```
197
+
198
+ ## Why Choose StateZero Over...
199
+
200
+ **🆚 HTMX:** Use modern React/Vue with full JavaScript ecosystem while keeping backend simplicity
201
+
202
+ **🆚 Firebase/Supabase:** Keep your Django backend, models, and business logic. No vendor lock-in.
203
+
204
+ **🆚 OpenAPI/GraphQL:** Get real-time updates and Django ORM power, not just basic CRUD
205
+
206
+ **🆚 Traditional REST APIs:** Write 90% less boilerplate. Focus on features, not data plumbing.
207
+
208
+ ## Pricing
209
+
210
+ StateZero uses a no-rugpull license model:
211
+
212
+ - **$0/month** for companies with revenue up to $3M
213
+ - **$75/month** for companies with revenue up to $7.5M
214
+ - **$200/month** for companies with revenue up to $20M
215
+ - **$500/month** for companies with revenue up to $100M
216
+ - **$1,000/month** for companies with revenue above $100M
217
+
218
+ Lock in your rate forever by signing up early. We can't change your fee or cancel your license.
219
+
220
+ ## Get Started
221
+
222
+ Run `pip install git+https://github.com/state-zero/statezero` and `npm install https://github.com/state-zero/statezero-client` to begin.