rebuildjs 0.22.2 → 0.24.1

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.
@@ -1,11 +1,12 @@
1
1
  import type { ctx__be_T, ctx__get_T, ctx__set_T, lock_memosig_T, memo_T } from 'ctx-core/rmemo'
2
- import type { Metafile } from 'esbuild'
3
2
  import type { has_app_T, has_middleware_T } from '../ctx/index.js'
3
+ import type { rebuildjs_metafile_T } from '../metafile_l0/index.js'
4
4
  export declare const browser__metafile_path$_:ctx__be_T<has_app_T, memo_T<string>, 'app'>
5
5
  export declare const browser__metafile_path_:ctx__get_T<has_app_T, string>
6
- export declare const browser__metafile$_:ctx__be_T<has_app_T, lock_memosig_T<Metafile|undefined>, 'app'>
7
- export declare const browser__metafile_:ctx__get_T<has_app_T, Metafile|undefined>
8
- export declare const browser__metafile__set:ctx__set_T<has_app_T, Metafile|undefined>
6
+ export declare const browser__metafile$_:ctx__be_T<has_app_T, lock_memosig_T<rebuildjs_metafile_T|undefined>, 'app'>
7
+ export declare const browser__metafile_:ctx__get_T<has_app_T, rebuildjs_metafile_T|undefined>
8
+ export declare const browser__metafile__set:ctx__set_T<has_app_T, rebuildjs_metafile_T|undefined>
9
+ export declare function browser__metafile__persist():Promise<void>
9
10
  export declare const browser__output__relative_path$_:ctx__be_T<has_middleware_T, memo_T<string>, 'middleware'>
10
11
  export declare const browser__output__relative_path_:ctx__get_T<has_middleware_T, string>
11
12
  export declare const browser__script$_:ctx__be_T<has_middleware_T, memo_T<string>, 'middleware'>
package/browser/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { file_exists_ } from 'ctx-core/fs'
2
2
  import { nullish__none_, waitfor } from 'ctx-core/function'
3
3
  import { be_lock_memosig_triple_, be_memo_pair_ } from 'ctx-core/rmemo'
4
- import { readFile } from 'node:fs/promises'
4
+ import { readFile, writeFile } from 'node:fs/promises'
5
5
  import { join, relative } from 'path'
6
6
  import { browser__relative_path_, browser_path_ } from '../app/index.js'
7
+ import { app_ctx } from '../ctx/index.js'
7
8
  import { server__output_ } from '../server/index.js'
8
9
  export const [
9
10
  browser__metafile_path$_,
@@ -16,22 +17,32 @@ export const [
16
17
  browser__metafile$_,
17
18
  browser__metafile_,
18
19
  browser__metafile__set
19
- ] = be_lock_memosig_triple_(()=>
20
- undefined,
21
- async (ctx, browser__metafile$)=>{
22
- browser__metafile__waitfor_promise?.cancel?.()
23
- let metafile_path
24
- if (!browser__metafile$.lock) {
25
- metafile_path = browser__metafile_path_(ctx)
26
- browser__metafile__waitfor_promise = waitfor(
27
- ()=>file_exists_(metafile_path),
28
- 200
29
- ).catch(()=>false)
30
- if (await browser__metafile__waitfor_promise && metafile_path === browser__metafile_path_(ctx)) {
31
- browser__metafile$._ = await readFile(metafile_path).then(buf=>JSON.parse(buf + ''))
20
+ ] = /** @type {be_lock_memosig_triple_T<rebuildjs_metafile_T>} */
21
+ be_lock_memosig_triple_(()=>
22
+ undefined,
23
+ async (ctx, browser__metafile$)=>{
24
+ browser__metafile__waitfor_promise?.cancel?.()
25
+ let metafile_path
26
+ if (!browser__metafile$.lock) {
27
+ metafile_path = browser__metafile_path_(ctx)
28
+ browser__metafile__waitfor_promise = waitfor(
29
+ ()=>file_exists_(metafile_path),
30
+ 200
31
+ ).catch(()=>false)
32
+ if (await browser__metafile__waitfor_promise && metafile_path === browser__metafile_path_(ctx)) {
33
+ browser__metafile$._ = await readFile(metafile_path).then(buf=>JSON.parse(buf + ''))
34
+ }
32
35
  }
33
- }
34
- }, { ns: 'app', id: 'browser__metafile' })
36
+ }, { ns: 'app', id: 'browser__metafile' })
37
+ export function browser__metafile__persist() {
38
+ return nullish__none_([
39
+ browser__metafile_path_(app_ctx),
40
+ browser__metafile_(app_ctx)
41
+ ], (browser__metafile_path, browser__metafile)=>
42
+ writeFile(
43
+ browser__metafile_path,
44
+ JSON.stringify(browser__metafile, null, '\t')))
45
+ }
35
46
  export const [
36
47
  browser__output__relative_path$_,
37
48
  browser__output__relative_path_
@@ -5,7 +5,12 @@ import { rmemo__wait } from 'ctx-core/rmemo'
5
5
  import esmock from 'esmock'
6
6
  import { test } from 'uvu'
7
7
  import { equal, throws } from 'uvu/assert'
8
- import { browser_metafile0, browser_metafile1, browser_metafile2, server_metafile0 } from '../_fixtures/index.js'
8
+ import {
9
+ browser__metafile0,
10
+ browser__metafile1,
11
+ browser__metafile2,
12
+ server__metafile0
13
+ } from '../_fixtures/metafiles.js'
9
14
  import { dist_path__set, is_prod__set } from '../app/index.js'
10
15
  import { app_ctx, middleware_ctx_ } from '../ctx/index.js'
11
16
  import { server__metafile__set, server__output_, server__output__relative_path__set } from '../server/index.js'
@@ -70,9 +75,9 @@ test('browser__metafile', async ()=>{
70
75
  readFile_path = path
71
76
  switch (path) {
72
77
  case '/cwd/dist0/browser/metafile.json':
73
- return Buffer.from(JSON.stringify(browser_metafile0), 'utf-8')
78
+ return Buffer.from(JSON.stringify(browser__metafile0), 'utf-8')
74
79
  case '/cwd/dist1/browser/metafile.json':
75
- return Buffer.from(JSON.stringify(browser_metafile1), 'utf-8')
80
+ return Buffer.from(JSON.stringify(browser__metafile1), 'utf-8')
76
81
  }
77
82
  }
78
83
  },
@@ -84,65 +89,65 @@ test('browser__metafile', async ()=>{
84
89
  _browser__metafile$_(app_ctx),
85
90
  m=>m,
86
91
  100)
87
- equal(_browser__metafile$_(app_ctx)._, browser_metafile0)
88
- equal(_browser__metafile_(app_ctx), browser_metafile0)
92
+ equal(_browser__metafile$_(app_ctx)._, browser__metafile0)
93
+ equal(_browser__metafile_(app_ctx), browser__metafile0)
89
94
  equal(file_exists__path, '/cwd/dist0/browser/metafile.json')
90
95
  equal(readFile_path, '/cwd/dist0/browser/metafile.json')
91
- equal(_browser__metafile$_(app_ctx)._, browser_metafile0)
92
- equal(_browser__metafile_(app_ctx), browser_metafile0)
96
+ equal(_browser__metafile$_(app_ctx)._, browser__metafile0)
97
+ equal(_browser__metafile_(app_ctx), browser__metafile0)
93
98
  dist_path__set(app_ctx, '/cwd/dist1')
94
99
  await rmemo__wait(
95
100
  _browser__metafile$_(app_ctx),
96
- m=>deep_equal(m, browser_metafile1),
101
+ m=>deep_equal(m, browser__metafile1),
97
102
  100)
98
- equal(_browser__metafile$_(app_ctx)._, browser_metafile1)
99
- equal(_browser__metafile_(app_ctx), browser_metafile1)
103
+ equal(_browser__metafile$_(app_ctx)._, browser__metafile1)
104
+ equal(_browser__metafile_(app_ctx), browser__metafile1)
100
105
  equal(file_exists__path, '/cwd/dist1/browser/metafile.json')
101
106
  equal(readFile_path, '/cwd/dist1/browser/metafile.json')
102
107
  dist_path__set(app_ctx, '/cwd/dist0')
103
108
  await rmemo__wait(
104
109
  _browser__metafile$_(app_ctx),
105
- m=>deep_equal(m, browser_metafile0),
110
+ m=>deep_equal(m, browser__metafile0),
106
111
  100)
107
- equal(_browser__metafile$_(app_ctx)._, browser_metafile0)
108
- equal(_browser__metafile_(app_ctx), browser_metafile0)
112
+ equal(_browser__metafile$_(app_ctx)._, browser__metafile0)
113
+ equal(_browser__metafile_(app_ctx), browser__metafile0)
109
114
  equal(file_exists__path, '/cwd/dist0/browser/metafile.json')
110
115
  equal(readFile_path, '/cwd/dist0/browser/metafile.json')
111
- _browser__metafile__set(app_ctx, browser_metafile2)
112
- equal(_browser__metafile$_(app_ctx)._, browser_metafile2)
113
- equal(_browser__metafile_(app_ctx), browser_metafile2)
116
+ _browser__metafile__set(app_ctx, browser__metafile2)
117
+ equal(_browser__metafile$_(app_ctx)._, browser__metafile2)
118
+ equal(_browser__metafile_(app_ctx), browser__metafile2)
114
119
  dist_path__set(app_ctx, '/cwd/dist1')
115
120
  let error_msg:string|undefined = undefined
116
121
  try {
117
122
  await rmemo__wait(
118
123
  _browser__metafile$_(app_ctx),
119
- m=>deep_equal(m, browser_metafile1),
124
+ m=>deep_equal(m, browser__metafile1),
120
125
  100)
121
126
  } catch (e) {
122
127
  error_msg = (e as Error).message
123
128
  }
124
- equal(_browser__metafile$_(app_ctx)._, browser_metafile2)
125
- equal(_browser__metafile_(app_ctx), browser_metafile2)
129
+ equal(_browser__metafile$_(app_ctx)._, browser__metafile2)
130
+ equal(_browser__metafile_(app_ctx), browser__metafile2)
126
131
  equal(error_msg, `Timeout 100ms`)
127
132
  // @ts-expect-error TS2345
128
133
  throws(()=>_browser__metafile$_(ctx_()))
129
134
  // @ts-expect-error TS2345
130
135
  throws(()=>_browser__metafile_(ctx_()))
131
136
  // @ts-expect-error TS2345
132
- throws(()=>_browser__metafile__set(ctx_(), browser_metafile0))
137
+ throws(()=>_browser__metafile__set(ctx_(), browser__metafile0))
133
138
  })
134
139
  test('browser__output__relative_path', ()=>{
135
140
  const middleware_ctx = middleware_ctx_()
136
141
  equal(browser__output__relative_path$_(middleware_ctx)._, undefined)
137
142
  equal(browser__output__relative_path_(middleware_ctx), undefined)
138
- server__metafile__set(middleware_ctx, server_metafile0)
143
+ server__metafile__set(middleware_ctx, server__metafile0)
139
144
  equal(browser__output__relative_path$_(middleware_ctx)._, undefined)
140
145
  equal(browser__output__relative_path_(middleware_ctx), undefined)
141
- browser__metafile__set(middleware_ctx, browser_metafile0)
146
+ browser__metafile__set(middleware_ctx, browser__metafile0)
142
147
  equal(browser__output__relative_path$_(middleware_ctx)._, undefined)
143
148
  equal(browser__output__relative_path_(middleware_ctx), undefined)
144
149
  server__output__relative_path__set(middleware_ctx, 'dist/server--dev/index.server-SVR0SVR0.js')
145
- equal(server_metafile0.outputs['dist/server--dev/index.server-SVR0SVR0.js'], {
150
+ equal(server__metafile0.outputs['dist/server--dev/index.server-SVR0SVR0.js'], {
146
151
  'imports': [],
147
152
  'exports': [],
148
153
  'entryPoint': 'src/app/index.server.ts',
@@ -154,7 +159,7 @@ test('browser__output__relative_path', ()=>{
154
159
  },
155
160
  'bytes': 98
156
161
  })
157
- equal(server__output_(middleware_ctx), server_metafile0.outputs['dist/server--dev/index.server-SVR0SVR0.js'])
162
+ equal(server__output_(middleware_ctx), server__metafile0.outputs['dist/server--dev/index.server-SVR0SVR0.js'])
158
163
  equal(browser__output__relative_path$_(middleware_ctx)._, 'dist/browser--dev/index.browser-BRS0BRS0.js')
159
164
  equal(browser__output__relative_path$_(middleware_ctx)._, 'dist/browser--dev/index.browser-BRS0BRS0.js')
160
165
  // @ts-expect-error TS2345
@@ -166,10 +171,10 @@ test('browser__script', ()=>{
166
171
  const middleware_ctx = middleware_ctx_()
167
172
  equal(browser__script$_(middleware_ctx)._, undefined)
168
173
  equal(browser__script_(middleware_ctx), undefined)
169
- server__metafile__set(middleware_ctx, server_metafile0)
174
+ server__metafile__set(middleware_ctx, server__metafile0)
170
175
  equal(browser__script$_(middleware_ctx)._, undefined)
171
176
  equal(browser__script_(middleware_ctx), undefined)
172
- browser__metafile__set(middleware_ctx, browser_metafile0)
177
+ browser__metafile__set(middleware_ctx, browser__metafile0)
173
178
  equal(browser__script$_(middleware_ctx)._, undefined)
174
179
  equal(browser__script_(middleware_ctx), undefined)
175
180
  server__output__relative_path__set(middleware_ctx, 'dist/server--dev/index.server-SVR0SVR0.js')
package/build/index.d.ts CHANGED
@@ -1,9 +1,16 @@
1
- import type { BuildOptions, Plugin } from 'esbuild'
2
- export declare function browser__build(config?:rebuildjs__build_config_T):Promise<void>
3
- export declare function server__build(config?:rebuildjs__build_config_T):Promise<void>
1
+ import type { ctx__be_T, ctx__get_T, ctx__set_T, sig_T } from 'ctx-core/rmemo'
2
+ import type { BuildContext, BuildOptions, Plugin } from 'esbuild'
3
+ import type { has_app_T } from '../ctx/index.js'
4
+ export declare const build_id$_:ctx__be_T<has_app_T, sig_T<string|undefined>, 'app'>
5
+ export declare const build_id_:ctx__get_T<has_app_T, string|undefined>
6
+ export declare const build_id__set:ctx__set_T<has_app_T, string|undefined>
7
+ export declare function build_id__refresh():string
8
+ export declare function browser__build(config?:rebuildjs_build_config_T):Promise<BuildContext>
9
+ export declare function server__build(config?:rebuildjs_build_config_T):Promise<BuildContext>
4
10
  export declare function server__external_(config?:Partial<BuildOptions>):Promise<string[]>
5
- export declare function rebuildjs__plugin_():Plugin
6
- export type rebuildjs__build_config_T = Partial<BuildOptions>&{ rebuildjs?: rebuildjs__plugin_config_T }
7
- export type rebuildjs__plugin_config_T = {
11
+ export declare function rebuildjs_plugin_():Plugin
12
+ export type rebuildjs_build_config_T =
13
+ Partial<BuildOptions>&{ rebuildjs?:rebuildjs_plugin_config_T }
14
+ export type rebuildjs_plugin_config_T = {
8
15
  watch?:boolean
9
16
  }
package/build/index.js CHANGED
@@ -1,16 +1,41 @@
1
+ /// <reference types="../metafile_l0/index.d.ts" />
1
2
  /// <reference types="./index.d.ts" />
2
- /** @typedef {import('esbuild').BuildOptions}BuildOptions */
3
- /** @typedef {import('esbuild').Plugin}Plugin */
4
- import { build, context } from 'esbuild'
3
+ import { nullish__none_, run } from 'ctx-core/function'
4
+ import { be, be_sig_triple_, memo_ } from 'ctx-core/rmemo'
5
+ import { short_uuid_ } from 'ctx-core/uuid'
6
+ import { context } from 'esbuild'
5
7
  import { fdir } from 'fdir'
6
- import { link, mkdir, rm, writeFile } from 'node:fs/promises'
8
+ import { link, mkdir, rm } from 'node:fs/promises'
7
9
  import { join, relative, resolve } from 'path'
8
10
  import { app_path_, browser_path_, cwd_, is_prod_, server__relative_path_, server_path_ } from '../app/index.js'
9
- import { browser__metafile__set } from '../browser/index.js'
11
+ import {
12
+ browser__metafile_,
13
+ browser__metafile__persist,
14
+ browser__metafile__set,
15
+ browser__output__relative_path_
16
+ } from '../browser/index.js'
10
17
  import { app_ctx } from '../ctx/index.js'
11
- import { server__metafile_, server__metafile__set } from '../server/index.js'
18
+ import { metafile__build_id_ } from '../metafile/index.js'
19
+ import {
20
+ server__metafile_,
21
+ server__metafile__persist,
22
+ server__metafile__set,
23
+ server__output__relative_path_M_middleware_ctx_
24
+ } from '../server/index.js'
25
+ export const [
26
+ build_id$_,
27
+ build_id_,
28
+ build_id__set,
29
+ ] = be_sig_triple_(()=>
30
+ undefined,
31
+ { id: 'build_id', ns: 'app' })
32
+ export function build_id__refresh() {
33
+ const build_id = Date.now() + '-' + short_uuid_()
34
+ build_id__set(app_ctx, build_id)
35
+ return build_id
36
+ }
12
37
  /**
13
- * @param {Plugin}config
38
+ * @param {import('esbuild').Plugin}config
14
39
  * @returns {Promise<void>}
15
40
  * @private
16
41
  */
@@ -31,8 +56,8 @@ export async function browser__build(config) {
31
56
  for (const path of path_a) {
32
57
  entryPoints.push(path)
33
58
  }
34
- const plugins = [rebuildjs__plugin_(), ...(esbuild__config.plugins || [])]
35
- /** @type {BuildOptions} */
59
+ const plugins = [rebuildjs_plugin_(), ...(esbuild__config.plugins || [])]
60
+ /** @type {import('esbuild').BuildOptions} */
36
61
  const esbuild_config = {
37
62
  entryNames: '[name]-[hash]',
38
63
  assetNames: '[name]-[hash]',
@@ -51,16 +76,17 @@ export async function browser__build(config) {
51
76
  outdir: browser_path_(app_ctx),
52
77
  plugins,
53
78
  }
79
+ const esbuild_ctx = await context(esbuild_config)
54
80
  if (rebuildjs?.watch ?? !is_prod_(app_ctx)) {
55
- const esbuild_ctx = await context(esbuild_config)
56
81
  await esbuild_ctx.watch()
57
82
  console.log('browser__build|watch')
58
83
  } else {
59
- await build(esbuild_config)
84
+ await esbuild_ctx.rebuild()
60
85
  }
86
+ return esbuild_ctx
61
87
  }
62
88
  /**
63
- * @param {rebuildjs__build_config_T}[config]
89
+ * @param {rebuildjs_build_config_T}[config]
64
90
  * @returns {Promise<void>}
65
91
  */
66
92
  export async function server__build(config) {
@@ -79,7 +105,7 @@ export async function server__build(config) {
79
105
  for (const path of path_a) {
80
106
  entryPoints.push(path)
81
107
  }
82
- const plugins = [rebuildjs__plugin_(), ...(esbuild__config.plugins || [])]
108
+ const plugins = [rebuildjs_plugin_(), ...(esbuild__config.plugins || [])]
83
109
  const esbuild_config = {
84
110
  entryNames: '[name]-[hash]',
85
111
  assetNames: '[name]-[hash]',
@@ -98,54 +124,167 @@ export async function server__build(config) {
98
124
  external: server__external_(esbuild__config),
99
125
  plugins,
100
126
  }
127
+ const esbuild_ctx = await context(esbuild_config)
101
128
  if (rebuildjs?.watch ?? !is_prod_(app_ctx)) {
102
- const esbuild_ctx = await context(esbuild_config)
103
129
  await esbuild_ctx.watch()
104
130
  console.log('server__build|watch')
105
131
  } else {
106
- await build(esbuild_config)
132
+ await esbuild_ctx.rebuild()
107
133
  }
134
+ return esbuild_ctx
108
135
  }
109
136
  /**
110
- * @param {rebuildjs__build_config_T}[config]
137
+ * @param {rebuildjs_build_config_T}[config]
111
138
  * @returns {Promise<string[]>}
112
139
  */
113
140
  export function server__external_(config) {
114
141
  return ['bun', 'node_modules/*', ...(config.external || [])]
115
142
  }
116
143
  /**
117
- * @returns {Plugin}
144
+ * @returns {import('esbuild').Plugin}
118
145
  * @private
146
+ *
119
147
  */
120
- export function rebuildjs__plugin_() {
121
- return {
122
- name: 'rebuildjs__plugin',
123
- setup(build) {
148
+ export function rebuildjs_plugin_() {
149
+ return { name: 'rebuildjs_plugin', setup: setup_() }
150
+ function setup_() {
151
+ /**
152
+ * @param {import('esbuild').PluginBuild}build
153
+ */
154
+ const setup = build=>{
124
155
  build.onEnd(async result=>{
125
- if (result.metafile) {
156
+ const {
157
+ /** @type {rebuildjs_metafile_T} */
158
+ metafile
159
+ } = result
160
+ if (metafile) {
126
161
  const { outdir } = build.initialOptions
127
162
  const resolve_outdir = resolve(outdir)
128
163
  if (resolve_outdir === server_path_(app_ctx)) {
129
- server__metafile__set(app_ctx, result.metafile)
164
+ const build_id = build_id__refresh()
165
+ await server__metafile__update(metafile, build_id)
166
+ if (build_id_(app_ctx) === build_id) {
167
+ await browser__metafile__update(browser__metafile_(app_ctx), build_id)
168
+ }
130
169
  } else if (resolve_outdir === browser_path_(app_ctx)) {
131
- browser__metafile__set(app_ctx, result.metafile)
132
- }
133
- if (outdir) {
134
- await writeFile(
135
- join(outdir, 'metafile.json'),
136
- JSON.stringify(result.metafile, null, 2))
170
+ const build_id = build_id__refresh()
171
+ await browser__metafile__update(metafile, build_id)
172
+ if (build_id_(app_ctx) === build_id) {
173
+ await server__metafile__update(server__metafile_(app_ctx), build_id)
174
+ }
137
175
  }
138
176
  }
139
- const outputs = server__metafile_(app_ctx)?.outputs ?? {}
140
- for (let output__relative_path in outputs) {
141
- if (/(\.js|\.mjs)(\.map)?$/.test(output__relative_path)) continue
142
- const asset_path = join(cwd_(app_ctx), output__relative_path)
143
- const link_path =
144
- join(browser_path_(app_ctx), relative(server__relative_path_(app_ctx), output__relative_path))
145
- await rm(link_path, { force: true })
146
- await link(asset_path, link_path)
147
- }
148
177
  })
149
178
  }
179
+ // Prevent GC
180
+ setup.rebuildjs__assets__link$ = rebuildjs__assets__link$_()
181
+ return setup
182
+ /**
183
+ *
184
+ * @returns {memo_T<void>}
185
+ * @private
186
+ */
187
+ function rebuildjs__assets__link$_() {
188
+ return (
189
+ be(app_ctx, ctx=>
190
+ run(memo_(assets__link$=>{
191
+ r()
192
+ return assets__link$
193
+ function r() {
194
+ nullish__none_([
195
+ build_id_(ctx),
196
+ metafile__build_id_(ctx),
197
+ server__metafile_(ctx),
198
+ cwd_(ctx),
199
+ browser_path_(ctx),
200
+ server__relative_path_(ctx),
201
+ ], (
202
+ build_id,
203
+ metafile__build_id,
204
+ server__metafile,
205
+ cwd,
206
+ browser_path,
207
+ server__relative_path,
208
+ )=>{
209
+ if (build_id === metafile__build_id) {
210
+ run(async ()=>{
211
+ const outputs = server__metafile.outputs ?? {}
212
+ for (let output__relative_path in outputs) {
213
+ if (/(\.js|\.mjs)(\.map)?$/.test(output__relative_path)) continue
214
+ const server_asset_path = join(cwd, output__relative_path)
215
+ const browser_asset_path = join(
216
+ browser_path,
217
+ relative(server__relative_path, output__relative_path))
218
+ if (cancel_()) return
219
+ await rm(browser_asset_path, { force: true })
220
+ if (cancel_()) return
221
+ await link(server_asset_path, browser_asset_path)
222
+ }
223
+ })
224
+ }
225
+ function cancel_() {
226
+ return (
227
+ build_id_(ctx) !== build_id
228
+ || metafile__build_id_(ctx) !== metafile__build_id
229
+ || server__metafile_(ctx) !== server__metafile
230
+ || cwd_(ctx) !== cwd
231
+ || browser_path_(ctx) !== browser_path
232
+ || server__relative_path_(ctx) !== server__relative_path
233
+ )
234
+ }
235
+ })
236
+ }
237
+ })),
238
+ { id: 'rebuildjs__assets__link$', ns: 'app' })
239
+ )
240
+ }
241
+ }
242
+ }
243
+ async function server__metafile__update(server__metafile, build_id) {
244
+ if (!server__metafile) return
245
+ server__metafile = {
246
+ ...server__metafile,
247
+ build_id,
248
+ rebuildjs_target: 'server'
249
+ }
250
+ server__metafile__set(app_ctx, server__metafile)
251
+ for (const [
252
+ server__output__relative_path,
253
+ middleware_ctx
254
+ ] of server__output__relative_path_M_middleware_ctx_(app_ctx).entries()) {
255
+ const output = server__metafile.outputs[server__output__relative_path]
256
+ const { cssBundle } = output
257
+ if (cssBundle) {
258
+ output.esbuild_cssBundle = cssBundle
259
+ output.cssBundle_content = [
260
+ server__output__relative_path,
261
+ ...(
262
+ browser__output__relative_path_(middleware_ctx)
263
+ ? [browser__output__relative_path_(middleware_ctx)]
264
+ : [])
265
+ ]
266
+ }
267
+ }
268
+ await server__metafile__persist()
269
+ }
270
+ async function browser__metafile__update(browser__metafile, build_id) {
271
+ if (!browser__metafile) return
272
+ browser__metafile = {
273
+ ...browser__metafile,
274
+ build_id,
275
+ rebuildjs_target: 'browser'
276
+ }
277
+ browser__metafile__set(app_ctx, browser__metafile)
278
+ for (const middleware_ctx of server__output__relative_path_M_middleware_ctx_(app_ctx)?.values?.() ?? []) {
279
+ const browser__output__relative_path = browser__output__relative_path_(middleware_ctx)
280
+ if (browser__output__relative_path) {
281
+ const output = browser__metafile.outputs[browser__output__relative_path]
282
+ const { cssBundle } = output
283
+ if (cssBundle) {
284
+ output.esbuild_cssBundle = cssBundle
285
+ output.cssBundle_content = [browser__output__relative_path]
286
+ }
287
+ }
150
288
  }
289
+ await browser__metafile__persist()
151
290
  }
@@ -1,11 +1,93 @@
1
+ import { ctx_ } from 'ctx-core/be'
2
+ import { file_exists_ } from 'ctx-core/fs'
3
+ import { sleep } from 'ctx-core/function'
4
+ import { BuildContext } from 'esbuild'
5
+ import { rm } from 'node:fs/promises'
6
+ import { dirname, join } from 'path'
1
7
  import { test } from 'uvu'
2
- import { equal } from 'uvu/assert'
3
- import './index.js'
8
+ import { equal, throws } from 'uvu/assert'
9
+ import { cwd__set } from '../app/index.js'
10
+ import { browser__metafile_ } from '../browser/index.js'
4
11
  import { app_ctx } from '../ctx/index.js'
12
+ import { metafile__wait } from '../metafile/index.js'
13
+ import { server__metafile_ } from '../server/index.js'
14
+ import { browser__build, build_id$_, build_id_, build_id__refresh, build_id__set, server__build } from './index.js'
5
15
  test.after.each(()=>{
6
16
  app_ctx.s.app.clear()
7
17
  })
8
- test('build|loads', ()=>{
9
- equal(1, 1)
18
+ test('build_id', ()=>{
19
+ equal(build_id$_(app_ctx)(), undefined)
20
+ equal(build_id_(app_ctx), undefined)
21
+ build_id__set(app_ctx, 'test_build_id')
22
+ equal(build_id$_(app_ctx)(), 'test_build_id')
23
+ equal(build_id_(app_ctx), 'test_build_id')
24
+ // @ts-expect-error TS2345
25
+ throws(()=>build_id$_(ctx_()))
26
+ // @ts-expect-error TS2345
27
+ throws(()=>build_id_(ctx_()))
28
+ })
29
+ test('build_id__refresh', ()=>{
30
+ equal(build_id_(app_ctx), undefined)
31
+ const build_id = build_id__refresh()
32
+ equal(build_id_(app_ctx), build_id)
33
+ equal(
34
+ parseInt(build_id.split('-')[0]) <= Date.now(),
35
+ true)
36
+ equal(
37
+ parseInt(build_id.split('-')[0]) > Date.now() - 1000,
38
+ true)
39
+ })
40
+ test('browser__build|server__build|rebuildjs_plugin_|metafile', async ()=>{
41
+ const test_dir = dirname(new URL(import.meta.url).pathname)
42
+ const cwd = join(test_dir, '../_fixtures')
43
+ cwd__set(app_ctx, cwd)
44
+ await rm(join(cwd, 'dist'), { recursive: true, force: true })
45
+ let server__build_context:BuildContext|undefined = undefined
46
+ let browser__build_context:BuildContext|undefined = undefined
47
+ try {
48
+ server__build_context = await server__build()
49
+ browser__build_context = await browser__build()
50
+ await metafile__wait()
51
+ equal(await file_exists_(join(cwd, 'dist')), true)
52
+ equal(await file_exists_(join(cwd, 'dist', 'browser--dev')), true)
53
+ equal(await file_exists_(join(cwd, 'dist', 'server--dev')), true)
54
+ const server__metafile = server__metafile_(app_ctx)!
55
+ equal(server__metafile.rebuildjs_target, 'server')
56
+ const browser__metafile = browser__metafile_(app_ctx)!
57
+ equal(browser__metafile.rebuildjs_target, 'browser')
58
+ equal(server__metafile.build_id != null, true)
59
+ equal(server__metafile.build_id, browser__metafile.build_id)
60
+ const server__output__relative_path =
61
+ Object.keys(server__metafile.outputs)
62
+ .find(server__output__relative_path=>
63
+ server__metafile.outputs[server__output__relative_path].entryPoint)!
64
+ equal(typeof server__output__relative_path, 'string')
65
+ const server__entryPoint__output =
66
+ server__metafile.outputs[server__output__relative_path]
67
+ equal(server__entryPoint__output != null, true)
68
+ equal(server__entryPoint__output.cssBundle != null, true)
69
+ equal(server__entryPoint__output.esbuild_cssBundle, server__entryPoint__output.cssBundle)
70
+ const browser__output__relative_path =
71
+ Object.keys(browser__metafile.outputs)
72
+ .find(browser__output__relative_path=>
73
+ browser__metafile.outputs[browser__output__relative_path].entryPoint)!
74
+ equal(typeof browser__output__relative_path, 'string')
75
+ const browser__entryPoint__output =
76
+ browser__metafile.outputs[browser__output__relative_path]
77
+ equal(browser__entryPoint__output != null, true)
78
+ equal(browser__entryPoint__output.cssBundle != null, true)
79
+ equal(browser__entryPoint__output.esbuild_cssBundle, browser__entryPoint__output.cssBundle)
80
+ equal(server__entryPoint__output.cssBundle_content, [
81
+ server__output__relative_path,
82
+ browser__output__relative_path
83
+ ])
84
+ equal(browser__entryPoint__output.cssBundle_content, [
85
+ browser__output__relative_path
86
+ ])
87
+ } finally {
88
+ await sleep(100)
89
+ server__build_context?.dispose?.()
90
+ browser__build_context?.dispose?.()
91
+ }
10
92
  })
11
93
  test.run()
package/ctx/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="./index.d.ts" />
2
2
  import { ns_ctx_ } from 'ctx-core/be'
3
- export const app_ctx = app_ctx_()
3
+ export const app_ctx = globalThis.rebuildjs__app_ctx ??= app_ctx_()
4
4
  /**
5
5
  * @returns {app_ctx_T}
6
6
  * @private
@@ -1 +1,6 @@
1
+ import type { ctx__be_T, ctx__get_T, memo_T } from 'ctx-core/rmemo'
2
+ import type { has_app_T } from '../ctx/index.js'
3
+ export * from '../metafile_l0/index.js'
4
+ export declare const metafile__build_id$_:ctx__be_T<has_app_T, memo_T<string>, 'app'>
5
+ export declare const metafile__build_id_:ctx__get_T<has_app_T, string>
1
6
  export declare function metafile__wait(timeout?:number):Promise<void>
package/metafile/index.js CHANGED
@@ -1,13 +1,27 @@
1
- import { memo_, rmemo__wait } from 'ctx-core/rmemo'
1
+ import { nullish__none_ } from 'ctx-core/function'
2
+ import { be_memo_pair_, rmemo__wait } from 'ctx-core/rmemo'
2
3
  import { browser__metafile_ } from '../browser/index.js'
3
4
  import { app_ctx } from '../ctx/index.js'
4
5
  import { server__metafile_ } from '../server/index.js'
6
+ export const [
7
+ metafile__build_id$_,
8
+ metafile__build_id_,
9
+ ] = be_memo_pair_((ctx, build_id$)=>
10
+ nullish__none_([server__metafile_(ctx), browser__metafile_(ctx)],
11
+ (server__metafile, browser__metafile)=>
12
+ server__metafile.build_id === browser__metafile.build_id
13
+ ? server__metafile.build_id
14
+ : build_id$.val),
15
+ { id: 'metafile__build_id', ns: 'app' })
5
16
  export async function metafile__wait(timeout = 5000) {
6
- await rmemo__wait(memo_(()=>
7
- server__metafile_(app_ctx) && browser__metafile_(app_ctx)),
8
- val=>val !== undefined,
9
- timeout
17
+ await rmemo__wait(
18
+ metafile__build_id$_(app_ctx),
19
+ metafile__build_id=>
20
+ metafile__build_id != null,
21
+ timeout
10
22
  ).catch(err=>{
11
- throw Error('metafile__wait|browser & server metafile timeout', { cause: err })
23
+ throw Error(
24
+ 'metafile__wait|browser__metafile & server__metafile timeout',
25
+ { cause: err })
12
26
  })
13
27
  }