spine-framework 0.1.50 → 0.1.51

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.
@@ -5,42 +5,27 @@
5
5
  * @layer cli
6
6
  * @stability stable
7
7
  *
8
- * `spine dev` command — unified development server for Spine.
9
- * Handles assembly, integrity verification, and Vite dev server startup.
10
- *
11
- * **Commands:**
12
- * | Subcommand | Description |
13
- * |-------------------|-------------------------------------------------------|
14
- * | `dev` | Start dev server with assembly and integrity check |
15
- * | `dev --no-verify` | Skip integrity verification (faster) |
16
- * | `dev --port 3002` | Use custom port (default: 3001) |
17
- * | `dev --watch` | Watch v2-custom for changes and auto-reassemble |
18
- * | `dev --no-watch` | Disable file watching (manual rebuild only) |
8
+ * `spine-framework dev` command — assemble and start the Netlify dev server.
19
9
  *
20
10
  * **What happens:**
21
- * 1. Runs `assemble:v2` to merge v2-core + v2-custom
22
- * 2. Runs `verify` to check core integrity (unless --no-verify)
23
- * 3. Starts Vite dev server on port 3001 (or --port)
24
- * 4. Watches v2-custom/ for changes (--watch by default)
25
- * 5. Fast incremental reassembly on custom code changes
11
+ * 1. Runs `npm run assemble` to merge framework + custom apps
12
+ * 2. Starts `netlify dev` (which runs Vite + Netlify Functions)
26
13
  *
27
14
  * **Usage:**
28
15
  * ```bash
29
- * spine dev
30
- * spine dev --port 3002
31
- * spine dev --no-verify
16
+ * spine-framework dev
17
+ * spine-framework dev --no-assemble # skip assembly step
32
18
  * ```
33
19
  *
34
- * @seeAlso scripts/assemble-v2.sh (assembly script)
35
- * @seeAlso scripts/verify-integrity.sh (verification script)
36
- * @seeAlso vite.config.ts (Vite configuration)
20
+ * @seeAlso scripts/assemble.sh (assembly script)
21
+ * @seeAlso netlify.toml (Netlify dev configuration)
37
22
  */
38
23
 
39
24
  import type { Command } from 'commander'
40
- import { spawn, execSync } from 'child_process'
25
+ import { spawn } from 'child_process'
41
26
  import { resolve, dirname } from 'path'
42
27
  import { fileURLToPath } from 'url'
43
- import { watch, existsSync, statSync, readdirSync } from 'fs'
28
+ import { existsSync } from 'fs'
44
29
 
45
30
  const __filename = fileURLToPath(import.meta.url)
46
31
  const __dirname = dirname(__filename)
@@ -51,131 +36,50 @@ const PROJECT_ROOT = process.cwd()
51
36
  export function registerDevCommands(program: Command) {
52
37
  program
53
38
  .command('dev')
54
- .description('Start Spine development server')
55
- .option('--no-verify', 'Skip integrity verification')
56
- .option('--port <port>', 'Dev server port', '3001')
57
- .option('--host', 'Expose to network', false)
58
- .option('--no-watch', 'Disable file watching')
59
- .option('--watch-delay <ms>', 'Debounce delay for reassembly', '500')
39
+ .description('Assemble and start the Netlify dev server')
40
+ .option('--no-assemble', 'Skip the assembly step')
60
41
  .action(async (opts) => {
61
42
  console.log('\n🚀 Starting Spine dev server...\n')
62
43
 
63
44
  try {
64
45
  // Step 1: Assembly
65
- console.log('📦 Step 1: Assembling v2-core + v2-custom...')
66
- const assemblyExitCode = await runCommand(
67
- 'bash',
68
- [resolve(PROJECT_ROOT, 'scripts/assemble-v2.sh')],
69
- PROJECT_ROOT
70
- )
71
-
72
- if (assemblyExitCode !== 0) {
73
- console.error('\n❌ Assembly failed. Please check the errors above.')
74
- process.exit(1)
75
- }
76
- console.log('✓ Assembly complete\n')
46
+ if (opts.assemble !== false) {
47
+ console.log('📦 Step 1: Assembling...')
48
+ const assemblyExitCode = await runCommand('npm', ['run', 'assemble'], PROJECT_ROOT)
77
49
 
78
- // Step 2: Integrity verification (unless skipped)
79
- if (opts.verify !== false) {
80
- console.log('🔒 Step 2: Verifying core integrity...')
81
- const verifyExitCode = await runCommand(
82
- 'bash',
83
- [resolve(PROJECT_ROOT, 'scripts/verify-integrity.sh')],
84
- PROJECT_ROOT
85
- )
86
-
87
- if (verifyExitCode !== 0) {
88
- console.warn('\n⚠️ Integrity check failed. Continuing anyway (--no-verify to skip)\n')
89
- } else {
90
- console.log('✓ Integrity verified\n')
50
+ if (assemblyExitCode !== 0) {
51
+ console.error('\n❌ Assembly failed. Please check the errors above.')
52
+ process.exit(1)
91
53
  }
54
+ console.log('✓ Assembly complete\n')
92
55
  } else {
93
- console.log('⏭️ Step 2: Skipping integrity verification (--no-verify)\n')
56
+ console.log('⏭️ Step 1: Skipping assembly (--no-assemble)\n')
94
57
  }
95
58
 
96
- // Step 3: Start Vite
97
- console.log(`🌐 Step 3: Starting Vite dev server on port ${opts.port}...`)
59
+ // Step 2: Start netlify dev
60
+ console.log('🌐 Step 2: Starting netlify dev...')
98
61
  console.log(' (Press Ctrl+C to stop)\n')
99
62
 
100
- const vite = spawn(
101
- resolve(PROJECT_ROOT, 'node_modules/.bin/vite'),
102
- [
103
- '--config', resolve(PROJECT_ROOT, 'vite.config.ts'),
104
- '--port', opts.port,
105
- ...(opts.host ? ['--host'] : [])
106
- ],
107
- {
108
- cwd: PROJECT_ROOT,
109
- stdio: 'inherit',
110
- env: { ...process.env, SPINE_DEV: 'true' }
111
- }
112
- )
113
-
114
- // Step 4: Watch v2-custom for changes (unless disabled)
115
- let watcher: ReturnType<typeof watch> | null = null
116
- if (opts.watch !== false) {
117
- const watchDelay = parseInt(opts.watchDelay) || 500
118
- const customDir = resolve(PROJECT_ROOT, 'v2-custom')
119
-
120
- if (existsSync(customDir)) {
121
- console.log(`👁️ Step 4: Watching v2-custom/ for changes...`)
122
- console.log(` (Changes trigger fast reassembly after ${watchDelay}ms debounce)\n`)
123
-
124
- let reassemblyTimeout: NodeJS.Timeout | null = null
125
-
126
- watcher = watch(customDir, { recursive: true }, (eventType, filename) => {
127
- // Ignore node_modules, .git, and temp files
128
- if (!filename || filename.includes('node_modules') || filename.startsWith('.')) {
129
- return
130
- }
131
-
132
- console.log(`\n📝 Change detected in v2-custom/${filename}`)
63
+ const netlifyBin = resolve(PROJECT_ROOT, 'node_modules/.bin/netlify')
64
+ const cmd = existsSync(netlifyBin) ? netlifyBin : 'netlify'
133
65
 
134
- // Debounce reassembly
135
- if (reassemblyTimeout) {
136
- clearTimeout(reassemblyTimeout)
137
- }
138
-
139
- reassemblyTimeout = setTimeout(async () => {
140
- console.log('🔧 Running fast reassembly...')
141
- try {
142
- const start = Date.now()
143
- await fastReassemble(PROJECT_ROOT)
144
- const duration = Date.now() - start
145
- console.log(`✓ Reassembly complete (${duration}ms)\n`)
146
- } catch (err: any) {
147
- console.error(`✗ Reassembly failed: ${err.message}\n`)
148
- }
149
- }, watchDelay)
150
- })
151
- } else {
152
- console.log('⏭️ Step 4: v2-custom/ not found, skipping watch mode\n')
153
- }
154
- } else {
155
- console.log('⏭️ Step 4: File watching disabled (--no-watch)\n')
156
- }
66
+ const netlify = spawn(cmd, ['dev'], {
67
+ cwd: PROJECT_ROOT,
68
+ stdio: 'inherit',
69
+ env: { ...process.env }
70
+ })
157
71
 
158
- vite.on('exit', (code) => {
159
- if (watcher) {
160
- watcher.close()
161
- }
72
+ netlify.on('exit', (code) => {
162
73
  process.exit(code || 0)
163
74
  })
164
75
 
165
- // Handle Ctrl+C gracefully
166
76
  process.on('SIGINT', () => {
167
- console.log('\n\n🛑 Shutting down dev server...')
168
- if (watcher) {
169
- watcher.close()
170
- }
171
- vite.kill('SIGTERM')
77
+ console.log('\n\n🛑 Shutting down...')
78
+ netlify.kill('SIGTERM')
172
79
  })
173
80
 
174
81
  process.on('SIGTERM', () => {
175
- if (watcher) {
176
- watcher.close()
177
- }
178
- vite.kill('SIGTERM')
82
+ netlify.kill('SIGTERM')
179
83
  })
180
84
 
181
85
  } catch (err: any) {
@@ -207,89 +111,3 @@ function runCommand(command: string, args: string[], cwd: string): Promise<numbe
207
111
  })
208
112
  })
209
113
  }
210
-
211
- /**
212
- * Fast incremental reassembly of v2-custom files only.
213
- * Uses rsync if available, falls back to selective copy.
214
- */
215
- async function fastReassemble(projectRoot: string): Promise<void> {
216
- const customDir = resolve(projectRoot, 'v2-custom')
217
- const srcDest = resolve(projectRoot, 'src/v2-assembled')
218
- const funcsDest = resolve(projectRoot, 'functions')
219
-
220
- // Check if rsync is available
221
- let hasRsync = false
222
- try {
223
- execSync('which rsync', { stdio: 'pipe' })
224
- hasRsync = true
225
- } catch {
226
- hasRsync = false
227
- }
228
-
229
- // Reassemble custom frontend files
230
- const customSrcDir = resolve(customDir, 'src')
231
- if (existsSync(customSrcDir)) {
232
- const destDir = srcDest
233
-
234
- if (hasRsync) {
235
- // Use rsync for efficient incremental sync
236
- execSync(
237
- `rsync -av --delete "${customSrcDir}/" "${destDir}/"`,
238
- { stdio: 'pipe', cwd: projectRoot }
239
- )
240
- } else {
241
- // Fallback: copy files that have changed
242
- copyChangedFiles(customSrcDir, destDir)
243
- }
244
- }
245
-
246
- // Reassemble custom function files
247
- const customFuncsDir = resolve(customDir, 'functions')
248
- if (existsSync(customFuncsDir)) {
249
- if (hasRsync) {
250
- execSync(
251
- `rsync -av --delete "${customFuncsDir}/" "${funcsDest}/"`,
252
- { stdio: 'pipe', cwd: projectRoot }
253
- )
254
- } else {
255
- copyChangedFiles(customFuncsDir, funcsDest)
256
- }
257
- }
258
- }
259
-
260
- /**
261
- * Copy only files that have changed (mtime comparison).
262
- * Fallback when rsync is not available.
263
- */
264
- function copyChangedFiles(src: string, dest: string): void {
265
- const files = readdirSync(src, { withFileTypes: true })
266
-
267
- for (const entry of files) {
268
- const srcPath = resolve(src, entry.name)
269
- const destPath = resolve(dest, entry.name)
270
-
271
- if (entry.isDirectory()) {
272
- if (!existsSync(destPath)) {
273
- // Create directory
274
- const { mkdirSync } = require('fs')
275
- mkdirSync(destPath, { recursive: true })
276
- }
277
- // Recurse
278
- copyChangedFiles(srcPath, destPath)
279
- } else {
280
- // Check if file needs copying
281
- const srcStat = statSync(srcPath)
282
- let needsCopy = true
283
-
284
- if (existsSync(destPath)) {
285
- const destStat = statSync(destPath)
286
- needsCopy = srcStat.mtime > destStat.mtime
287
- }
288
-
289
- if (needsCopy) {
290
- const { copyFileSync } = require('fs')
291
- copyFileSync(srcPath, destPath)
292
- }
293
- }
294
- }
295
- }
@@ -4,35 +4,20 @@
4
4
  * @layer cli
5
5
  * @stability stable
6
6
  *
7
- * `spine dev` command — unified development server for Spine.
8
- * Handles assembly, integrity verification, and Vite dev server startup.
9
- *
10
- * **Commands:**
11
- * | Subcommand | Description |
12
- * |-------------------|-------------------------------------------------------|
13
- * | `dev` | Start dev server with assembly and integrity check |
14
- * | `dev --no-verify` | Skip integrity verification (faster) |
15
- * | `dev --port 3002` | Use custom port (default: 3001) |
16
- * | `dev --watch` | Watch v2-custom for changes and auto-reassemble |
17
- * | `dev --no-watch` | Disable file watching (manual rebuild only) |
7
+ * `spine-framework dev` command — assemble and start the Netlify dev server.
18
8
  *
19
9
  * **What happens:**
20
- * 1. Runs `assemble:v2` to merge v2-core + v2-custom
21
- * 2. Runs `verify` to check core integrity (unless --no-verify)
22
- * 3. Starts Vite dev server on port 3001 (or --port)
23
- * 4. Watches v2-custom/ for changes (--watch by default)
24
- * 5. Fast incremental reassembly on custom code changes
10
+ * 1. Runs `npm run assemble` to merge framework + custom apps
11
+ * 2. Starts `netlify dev` (which runs Vite + Netlify Functions)
25
12
  *
26
13
  * **Usage:**
27
14
  * ```bash
28
- * spine dev
29
- * spine dev --port 3002
30
- * spine dev --no-verify
15
+ * spine-framework dev
16
+ * spine-framework dev --no-assemble # skip assembly step
31
17
  * ```
32
18
  *
33
- * @seeAlso scripts/assemble-v2.sh (assembly script)
34
- * @seeAlso scripts/verify-integrity.sh (verification script)
35
- * @seeAlso vite.config.ts (Vite configuration)
19
+ * @seeAlso scripts/assemble.sh (assembly script)
20
+ * @seeAlso netlify.toml (Netlify dev configuration)
36
21
  */
37
22
  import type { Command } from 'commander';
38
23
  export declare function registerDevCommands(program: Command): void;
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/dev.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYxC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QA0InD"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../.framework/cli/commands/dev.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYxC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QAyDnD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spine-framework",
3
- "version": "0.1.50",
3
+ "version": "0.1.51",
4
4
  "private": false,
5
5
  "description": "Spine — enterprise application framework built on Supabase + Netlify + React",
6
6
  "type": "module",