ember-vite-hmr 1.5.5 → 1.6.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.
package/README.md CHANGED
@@ -7,7 +7,9 @@ this can hot reload
7
7
  - helpers
8
8
  - modifiers
9
9
  - components + templates, fcct components and its deps
10
- - routes/controllers/route-templates (although it refreshes the whole route and thus looses all state)
10
+ - routes/controllers/route-templates
11
+
12
+ this tries to keep the state of properties in components and controller
11
13
 
12
14
  it cannot hot reload local properties that turn out to be helpers/modifiers/components.
13
15
 
@@ -272,9 +272,12 @@ function hotReplaceAst(babel) {
272
272
  'default';
273
273
  const ast = (0, core_1.parse)(`
274
274
  (async () => {
275
- const c = await import('/ember-vite-hmr/virtual/component:${source}:${specifierName}.gjs');
275
+ const c = await import('/ember-vite-hmr/virtual/component:${source}:${specifierName}.gjs?timestamp=${Date.now()}');
276
276
  ${exports.hotAstProcessor.meta.importVar}.${imp} = c.default;
277
277
  })()
278
+ import.meta.hot.accept('/ember-vite-hmr/virtual/component:${source}:${specifierName}.gjs', (c) => {
279
+ ${exports.hotAstProcessor.meta.importVar}.${imp} = c['${specifierName}'];
280
+ });
278
281
  import.meta.hot.accept('${source}');
279
282
  `);
280
283
  const importVirtual = ast.program.body;
package/dist/lib/hmr.js CHANGED
@@ -15,7 +15,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.hmr = hmr;
16
16
  const path_1 = __importDefault(require("path"));
17
17
  const core_1 = require("@babel/core");
18
- const getHotComponent = (imp, specifier) => `
18
+ const fs_1 = require("fs");
19
+ function generateContent(yields) {
20
+ if (!yields.includes('default')) {
21
+ yields.push('default');
22
+ }
23
+ let all = yields.map((y) => `(has-block '${y}')`).join(' ');
24
+ let str = '';
25
+ for (const y of yields) {
26
+ str += `
27
+ <:${y} as |a b c d e f g h i j k l|>{{yield a b c d e f g h i j k l to='${y}'}}</:${y}>
28
+ `;
29
+ }
30
+ return `
31
+ {{#if (notAny ${all})}}
32
+ <this.curried @__hot__={{this.hot}} />
33
+ {{else}}
34
+ <this.curried @__hot__={{this.hot}} >
35
+ ${str}
36
+ </this.curried>
37
+ {{/if}}
38
+ `;
39
+ }
40
+ const getHotComponent = (imp, specifier, yields) => `
19
41
  import { ${specifier} as TargetComponent } from "${imp}";
20
42
  import Component from "@glimmer/component";
21
43
  import { tracked } from "@glimmer/tracking";
@@ -23,6 +45,10 @@ import { createComputeRef } from "@glimmer/reference";
23
45
  import { curry } from '@glimmer/runtime';
24
46
  import { CurriedTypes } from '@glimmer/vm';
25
47
 
48
+ function notAny(...yields) {
49
+ return !yields.some((y) => !!y);
50
+ }
51
+
26
52
  export default class HotComponent extends Component {
27
53
  @tracked curried;
28
54
  hot = {};
@@ -42,16 +68,50 @@ export default class HotComponent extends Component {
42
68
  }
43
69
  }
44
70
  <template>
45
- <this.curried @__hot__={{this.hot}}></this.curried>
71
+ ${generateContent(yields)}
46
72
  </template>
47
73
  }
48
74
  `;
75
+ const cachedYields = {};
76
+ function getYieldsFromFile(filename, noCache) {
77
+ if (cachedYields[filename] && !noCache) {
78
+ return cachedYields[filename];
79
+ }
80
+ const content = (0, fs_1.readFileSync)(filename).toString();
81
+ // very basic, todo: make this use AST
82
+ const matches = content.matchAll(/to=['"](\w+)['"]/g);
83
+ const yields = new Set([...matches].map((m) => m === null || m === void 0 ? void 0 : m[1]).filter((m) => !!m));
84
+ if (noCache) {
85
+ return {
86
+ yields,
87
+ modules: [],
88
+ };
89
+ }
90
+ cachedYields[filename] = {
91
+ yields,
92
+ modules: [],
93
+ };
94
+ return cachedYields[filename];
95
+ }
96
+ function difference(a, b) {
97
+ const diff = [];
98
+ for (const bElement of b) {
99
+ if (!a.has(bElement)) {
100
+ diff.push(bElement);
101
+ }
102
+ }
103
+ return diff;
104
+ }
49
105
  const virtualPrefix = '/ember-vite-hmr/virtual/component:';
50
106
  function hmr(enableViteHmrForModes = ['development']) {
51
107
  let conf;
108
+ let server;
52
109
  return {
53
110
  name: 'hmr-plugin',
54
111
  enforce: 'post',
112
+ configureServer(s) {
113
+ server = s;
114
+ },
55
115
  configResolved(config) {
56
116
  conf = config;
57
117
  process.env['EMBER_VITE_HMR_ENABLED'] = enableViteHmrForModes
@@ -77,12 +137,38 @@ function hmr(enableViteHmrForModes = ['development']) {
77
137
  }
78
138
  },
79
139
  load(id) {
80
- if (id.startsWith(virtualPrefix)) {
81
- const [imp, specifier] = id
82
- .slice(virtualPrefix.length, -'.gts'.length)
83
- .split(':');
84
- return getHotComponent(imp, specifier);
85
- }
140
+ return __awaiter(this, void 0, void 0, function* () {
141
+ if (cachedYields[id] &&
142
+ difference(cachedYields[id].yields, getYieldsFromFile(id, true).yields).length) {
143
+ for (const y of getYieldsFromFile(id, true).yields) {
144
+ cachedYields[id].yields.add(y);
145
+ }
146
+ const modules = cachedYields[id].modules;
147
+ delete cachedYields[id];
148
+ for (const module of modules) {
149
+ server.moduleGraph.onFileChange(module);
150
+ let m = server.moduleGraph.getModuleById(module);
151
+ if (m) {
152
+ yield server.reloadModule(m);
153
+ }
154
+ }
155
+ }
156
+ if (id.startsWith(virtualPrefix)) {
157
+ const [imp, specifier] = id
158
+ .split('?')[0]
159
+ .slice(virtualPrefix.length, -'.gts'.length)
160
+ .split(':');
161
+ let filename = imp;
162
+ if (filename.includes('__vpc__')) {
163
+ filename = filename.split('__vpc__')[0];
164
+ }
165
+ const resolved = yield this.resolve(filename, id);
166
+ const cached = getYieldsFromFile(resolved.id);
167
+ const yields = cached.yields;
168
+ cached.modules.push(id);
169
+ return getHotComponent(imp, specifier, [...yields].filter((y) => !!y));
170
+ }
171
+ });
86
172
  },
87
173
  transformIndexHtml(html) {
88
174
  if (process.env['EMBER_VITE_HMR_ENABLED'] !== 'true') {
@@ -155,7 +241,7 @@ function hmr(enableViteHmrForModes = ['development']) {
155
241
  return id;
156
242
  });
157
243
  const result = [
158
- ...source.matchAll(/import.meta.hot.accept\('([^']+)'/g),
244
+ ...source.matchAll(/import.meta.hot.accept\(['"]([^'"]+)['"]/g),
159
245
  ];
160
246
  for (const resultElement of result) {
161
247
  const dep = resultElement[1];
@@ -166,8 +252,9 @@ function hmr(enableViteHmrForModes = ['development']) {
166
252
  continue;
167
253
  didReplaceSources = true;
168
254
  source = source.replace(`import.meta.hot.accept('${dep}'`, `import.meta.hot.accept('${id}'`);
255
+ source = source.replace(`import.meta.hot.accept("${dep}"`, `import.meta.hot.accept("${id}"`);
169
256
  }
170
- const importMatches = [...source.matchAll(/import\('([^']+)'/g)];
257
+ const importMatches = [...source.matchAll(/import\(['"]([^']+)['"]/g)];
171
258
  for (const resultElement of importMatches) {
172
259
  const dep = resultElement[1];
173
260
  if (!dep.startsWith(virtualPrefix)) {
@@ -183,6 +270,7 @@ function hmr(enableViteHmrForModes = ['development']) {
183
270
  continue;
184
271
  didReplaceSources = true;
185
272
  source = source.replace(`import('${virtualPrefix}${imp}`, `import('${virtualPrefix}${id}`);
273
+ source = source.replace(`import("${virtualPrefix}${imp}`, `import("${virtualPrefix}${id}`);
186
274
  }
187
275
  }
188
276
  if (didReplaceSources) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-vite-hmr",
3
- "version": "1.5.5",
3
+ "version": "1.6.0",
4
4
  "keywords": [
5
5
  "ember-addon"
6
6
  ],