@voxgig/model 3.5.0 → 5.0.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 (47) hide show
  1. package/bin/voxgig-model +150 -31
  2. package/dist/{lib/build.d.ts → build.d.ts} +6 -5
  3. package/dist/{lib/build.js → build.js} +4 -3
  4. package/dist/build.js.map +1 -0
  5. package/dist/{lib/builder → builder}/local.js +13 -34
  6. package/dist/builder/local.js.map +1 -0
  7. package/dist/{lib/builder → builder}/model.js +5 -0
  8. package/dist/builder/model.js.map +1 -0
  9. package/dist/config.d.ts +12 -0
  10. package/dist/{lib/config.js → config.js} +6 -4
  11. package/dist/config.js.map +1 -0
  12. package/dist/model.d.ts +8 -7
  13. package/dist/model.js +35 -20
  14. package/dist/model.js.map +1 -1
  15. package/dist/tsconfig.tsbuildinfo +1 -0
  16. package/dist/{lib/types.d.ts → types.d.ts} +25 -3
  17. package/dist/types.js +4 -0
  18. package/dist/types.js.map +1 -0
  19. package/dist/{lib/watch.d.ts → watch.d.ts} +15 -18
  20. package/dist/watch.js +227 -0
  21. package/dist/watch.js.map +1 -0
  22. package/package.json +19 -20
  23. package/dist/lib/build.js.map +0 -1
  24. package/dist/lib/builder/local.js.map +0 -1
  25. package/dist/lib/builder/model.js.map +0 -1
  26. package/dist/lib/config.d.ts +0 -11
  27. package/dist/lib/config.js.map +0 -1
  28. package/dist/lib/model-builder.d.ts +0 -0
  29. package/dist/lib/model-builder.js +0 -2
  30. package/dist/lib/model-builder.js.map +0 -1
  31. package/dist/lib/types.js +0 -3
  32. package/dist/lib/types.js.map +0 -1
  33. package/dist/lib/util.d.ts +0 -7
  34. package/dist/lib/util.js +0 -94
  35. package/dist/lib/util.js.map +0 -1
  36. package/dist/lib/watch.js +0 -172
  37. package/dist/lib/watch.js.map +0 -1
  38. package/dist/model.min.js +0 -94
  39. package/lib/build.ts +0 -138
  40. package/lib/builder/local.ts +0 -130
  41. package/lib/builder/model.ts +0 -37
  42. package/lib/config.ts +0 -50
  43. package/lib/types.ts +0 -67
  44. package/lib/watch.ts +0 -250
  45. package/model.ts +0 -145
  46. /package/dist/{lib/builder → builder}/local.d.ts +0 -0
  47. /package/dist/{lib/builder → builder}/model.d.ts +0 -0
package/lib/watch.ts DELETED
@@ -1,250 +0,0 @@
1
- /* Copyright © 2021-2024 Voxgig Ltd, MIT License. */
2
-
3
- import Path from 'node:path'
4
-
5
-
6
- import type { Build, BuildResult } from './types'
7
-
8
- import { makeBuild } from './build'
9
- import { FSWatcher } from 'chokidar'
10
-
11
- import { readFile, stat } from 'fs/promises'
12
-
13
-
14
- const print = console.log
15
- const warn = console.warn
16
-
17
-
18
- type Run = {
19
- canon: string
20
- path: string
21
- start: number
22
- end: number
23
- }
24
-
25
- type Canon = {
26
- path: string
27
- isFolder: boolean
28
- when: number
29
- }
30
-
31
- class Watch {
32
- fsw: FSWatcher
33
- spec: any
34
- last?: BuildResult
35
- last_change_time: number
36
- build: Build | undefined
37
- runq: Run[]
38
- doneq: Run[]
39
- canons: Canon[]
40
- running: boolean
41
-
42
- constructor(spec: any) {
43
- this.spec = spec
44
- this.fsw = new FSWatcher()
45
- this.last_change_time = 0
46
- this.runq = []
47
- this.doneq = []
48
- this.canons = []
49
- this.running = false
50
-
51
- // const run = this.run.bind(this)
52
- const drain = this.drain.bind(this)
53
-
54
- this.fsw.on('change', async (path: string) => {
55
- // TODO: needs a much more robust queue that checks for dups,
56
- // otherwise BuildContext state will have concurrency corruptions
57
- // Avoid rebuilding when, for example, TS rewrites all files in dist
58
- // const dorun = 1111 < Date.now() - this.last_change_time
59
- // console.log('CHANGE', dorun, this.last_change_time, args)
60
-
61
- const canon = this.canon(path)
62
-
63
- const running = this.runq.find((run: Run) => run.canon === canon)
64
- if (running) {
65
- // console.log('RUNNING', canon, path)
66
- return
67
- }
68
-
69
- this.runq.push({
70
- canon,
71
- path,
72
- start: Date.now(),
73
- end: -1,
74
- })
75
-
76
- // console.log('RUNQ-ADD', this.runq)
77
- setImmediate(drain)
78
- })
79
- }
80
-
81
-
82
- async drain() {
83
- if (this.running) {
84
- return
85
- }
86
-
87
- this.running = true
88
- let r
89
- while (r = this.runq[0]) {
90
- // console.log('DRAIN')
91
- let br = await this.run(false, r.canon)
92
- // console.log('BR', br)
93
- this.runq.shift()
94
- r.end = Date.now()
95
-
96
- this.doneq.push(r)
97
-
98
- // console.log('DONEQ', this.doneq)
99
- }
100
- this.running = false
101
- }
102
-
103
-
104
- async add(path: string) {
105
- if (!Path.isAbsolute(path)) {
106
- path = Path.join(this.spec.require, path)
107
- }
108
-
109
- // Ignore if aleady added
110
- if (this.canons.find((c: Canon) => c.path === path)) {
111
- return
112
- }
113
-
114
- const fileStat = await stat(path)
115
- const canon: Canon = {
116
- path: path,
117
- isFolder: fileStat.isDirectory(),
118
- when: Date.now()
119
- }
120
-
121
- this.canons.push(canon)
122
-
123
- this.fsw.add(path)
124
-
125
- // console.log('ADD', canon)
126
- }
127
-
128
-
129
- // If path is inside a watched folder, return folder as canonical reference.
130
- canon(path: string) {
131
- for (const canon of this.canons) {
132
- if (canon.isFolder && path.startsWith(canon.path)) {
133
- return canon.path
134
- }
135
- }
136
- return path
137
- }
138
-
139
-
140
- async update(br: BuildResult) {
141
- let build = (br.build as Build)
142
-
143
- let files: string[] =
144
- Object.keys(build.root.deps).reduce((files: string[], target: any) => {
145
- files = files.concat(Object.keys(build.root.deps[target]))
146
- return files
147
- }, [build.path])
148
-
149
-
150
- // TODO: remove deleted files
151
- files.forEach(async (file: string) => {
152
- if ('string' === typeof (file) &&
153
- '' !== file &&
154
- build.opts.base !== file
155
- ) {
156
- await this.add(file)
157
- }
158
- })
159
-
160
- }
161
-
162
-
163
- // Returns first BuildResult
164
- async start(): Promise<BuildResult> {
165
- return await this.run(false, '<start>')
166
- }
167
-
168
-
169
- async run(once?: boolean, trigger?: string): Promise<BuildResult> {
170
- // console.trace()
171
-
172
- this.last_change_time = Date.now()
173
- print('\n@voxgig/model', this.last_change_time, new Date(this.last_change_time))
174
- print('TRIGGER:', trigger, '\n')
175
-
176
- // TODO: build spec should not have src!
177
- let src = (await readFile(this.spec.path)).toString()
178
- this.spec.src = src
179
-
180
- this.build = this.build || makeBuild(this.spec)
181
-
182
- // TODO: better way to do this?
183
- this.build.src = src
184
-
185
- let br: BuildResult = await this.build.run()
186
-
187
- print('\nFILES:\n' + this.descDeps((br as any).build.root.deps) + '\n')
188
-
189
- if (br.ok) {
190
- print('TOP:', Object.keys(br?.build?.model).join(', '), '\n')
191
-
192
- if (!once) {
193
- // There may be new files.
194
- await this.update(br)
195
- }
196
- }
197
- else {
198
- warn('MODEL ERRORS: ' + br.err?.length)
199
- this.handleErrors(br)
200
- }
201
-
202
- this.last = br
203
-
204
- return br
205
- }
206
-
207
-
208
- async stop() {
209
- await this.fsw.close()
210
- }
211
-
212
-
213
- handleErrors(br: BuildResult) {
214
- if (br.err) {
215
- for (let be of br.err) {
216
- // TODO: print stack if not a model error
217
-
218
- if (be.isVal && be.msg) {
219
- warn(be.msg)
220
- }
221
- // else if (be.message) {
222
- // warn(be.message)
223
- // }
224
- else {
225
- warn(be)
226
- }
227
- }
228
- }
229
- }
230
-
231
- descDeps(deps: Record<string, Record<string, { tar: string }>>) {
232
- if (null == deps) {
233
- return ''
234
- }
235
-
236
- let desc = []
237
- for (let entryPath of Object.keys(deps)) {
238
- desc.push(' ' + entryPath)
239
- for (let depPath of Object.keys(deps[entryPath])) {
240
- desc.push(' ' + depPath)
241
- }
242
- }
243
- return desc.join('\n')
244
- }
245
- }
246
-
247
-
248
- export {
249
- Watch
250
- }
package/model.ts DELETED
@@ -1,145 +0,0 @@
1
- /* Copyright © 2021-2023 Voxgig Ltd, MIT License. */
2
-
3
- // TODO: remove need for this
4
- import Fs from 'fs'
5
-
6
-
7
- import type { Build, BuildResult, BuildAction, BuildContext, Spec } from './lib/types'
8
-
9
-
10
- import { Config } from './lib/config'
11
- import { Watch } from './lib/watch'
12
-
13
- import { model_builder } from './lib/builder/model'
14
- import { local_builder } from './lib/builder/local'
15
-
16
-
17
- class Model {
18
- config: Config
19
- build: any
20
- watch: Watch
21
-
22
- trigger_model = false
23
-
24
-
25
- constructor(spec: Spec) {
26
- const self = this
27
-
28
- // Config is a special Watch to handle model config.
29
- this.config = makeConfig(spec, {
30
- path: '/',
31
- build: async function trigger_model(build: Build, ctx: BuildContext) {
32
- if ('post' !== ctx.step) {
33
- return { ok: true }
34
- }
35
-
36
- let res
37
-
38
- // console.log('TRIGGER', build.id, self.trigger_model, ctx)
39
- // console.log(new Error().stack)
40
-
41
- if (self.trigger_model) {
42
-
43
- // TODO: fix!!!
44
- self.build.use.config.watch.last.build = build
45
-
46
- res = self.watch.run(true)
47
- }
48
- else {
49
- self.trigger_model = true
50
- res = { ok: true }
51
- }
52
-
53
- const watchmap = build.model?.sys?.model?.watch
54
-
55
- if (watchmap) {
56
- Object.keys(watchmap).map((file: string) => {
57
- self.watch.add(file)
58
- })
59
- }
60
-
61
- return res
62
- }
63
- })
64
-
65
-
66
- // The actual model.
67
- this.build = {
68
- src: spec.src,
69
- path: spec.path,
70
- base: spec.base,
71
- use: { config: self.config },
72
- res: [
73
- {
74
- path: '/',
75
- build: model_builder
76
- },
77
- {
78
- path: '/',
79
- build: local_builder
80
- }
81
- ],
82
- require: spec.require
83
- }
84
-
85
-
86
- this.watch = new Watch(self.build)
87
- }
88
-
89
-
90
- async run(): Promise<BuildResult> {
91
- this.trigger_model = false
92
- const br = await this.config.run()
93
- return br.ok ? this.watch.run(true) : br
94
- }
95
-
96
-
97
- async start(): Promise<BuildResult> {
98
- this.trigger_model = false
99
- const br = await this.config.start()
100
- return br.ok ? this.watch.start() : br
101
- }
102
-
103
-
104
- async stop() {
105
- return this.watch.stop()
106
- }
107
- }
108
-
109
-
110
- function makeConfig(spec: Spec, trigger_model_build: BuildAction) {
111
- let cbase = spec.base + '/.model-config'
112
- let cpath = cbase + '/model-config.jsonic'
113
-
114
- // Build should load file
115
- let src = Fs.readFileSync(cpath).toString()
116
-
117
- let cspec: Spec = {
118
- src: src,
119
- path: cpath,
120
- base: cbase,
121
- res: [
122
-
123
- // Generate full config model and save as a file.
124
- {
125
- path: '/',
126
- build: model_builder
127
- },
128
-
129
- // Trigger main model build.
130
- trigger_model_build
131
- ],
132
- require: spec.require
133
- }
134
-
135
- return new Config(cspec)
136
- }
137
-
138
-
139
-
140
- export {
141
- Model,
142
- Spec,
143
- }
144
-
145
-
File without changes
File without changes