@bookshop/hugo-engine 3.3.2 → 3.4.0-alpha.2

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 (96) hide show
  1. package/.nyc_output/{396c364e-fec4-4f27-9ff2-8b236061ef8f.json → 0f70a16f-6a79-48c7-8b16-3b4665e247b2.json} +0 -0
  2. package/.nyc_output/{4ef43740-059b-4329-96cd-0643fd8fe8d8.json → 6285d5fa-be3d-49e4-8f2f-82157d95dcd8.json} +0 -0
  3. package/.nyc_output/{656275f4-66d6-4d27-bfab-c2f7a3087670.json → 8b5e1314-6e86-4197-a3ae-3c40e4c2f39e.json} +0 -0
  4. package/.nyc_output/{6aec5420-0b83-4260-b300-4d595dfd0660.json → c5490eb0-70c0-468f-a43f-e58c75dd34c8.json} +0 -0
  5. package/.nyc_output/{874bd79b-45da-4726-9afc-1f6cab44be1f.json → ee1a9bec-d318-4aea-af93-7269debcf6df.json} +0 -0
  6. package/.nyc_output/processinfo/{396c364e-fec4-4f27-9ff2-8b236061ef8f.json → 0f70a16f-6a79-48c7-8b16-3b4665e247b2.json} +1 -1
  7. package/.nyc_output/processinfo/6285d5fa-be3d-49e4-8f2f-82157d95dcd8.json +1 -0
  8. package/.nyc_output/processinfo/{4ef43740-059b-4329-96cd-0643fd8fe8d8.json → 8b5e1314-6e86-4197-a3ae-3c40e4c2f39e.json} +1 -1
  9. package/.nyc_output/processinfo/{656275f4-66d6-4d27-bfab-c2f7a3087670.json → c5490eb0-70c0-468f-a43f-e58c75dd34c8.json} +1 -1
  10. package/.nyc_output/processinfo/{874bd79b-45da-4726-9afc-1f6cab44be1f.json → ee1a9bec-d318-4aea-af93-7269debcf6df.json} +1 -1
  11. package/.nyc_output/processinfo/index.json +1 -1
  12. package/bookshop-hugo-templates/bookshop.html +56 -0
  13. package/bookshop-hugo-templates/bookshop_bindings.html +29 -0
  14. package/bookshop-hugo-templates/bookshop_component_browser.html +30 -0
  15. package/bookshop-hugo-templates/bookshop_partial.html +42 -0
  16. package/bookshop-hugo-templates/bookshop_scss.html +9 -0
  17. package/bookshop-hugo-templates/errors/bad_bookshop_tag.html +39 -0
  18. package/bookshop-hugo-templates/errors/err.html +6 -0
  19. package/bookshop-hugo-templates/helpers/component.html +25 -0
  20. package/bookshop-hugo-templates/helpers/component_key.html +11 -0
  21. package/bookshop-hugo-templates/helpers/partial.html +25 -0
  22. package/bookshop-hugo-templates/helpers/partial_key.html +9 -0
  23. package/full-hugo-renderer/build.sh +34 -0
  24. package/full-hugo-renderer/go.mod +87 -0
  25. package/{hugo-renderer → full-hugo-renderer}/go.sum +204 -12
  26. package/full-hugo-renderer/hugo_renderer.wasm +0 -0
  27. package/full-hugo-renderer/hugo_renderer.wasm.gz +0 -0
  28. package/full-hugo-renderer/main.go +215 -0
  29. package/{hugo-renderer → full-hugo-renderer}/wasm_exec.js +6 -2
  30. package/lib/builder.js +2 -2
  31. package/lib/engine.js +109 -42
  32. package/lib/hugoIdentifierParser.js +5 -0
  33. package/lib/translateTextTemplate.js +3 -0
  34. package/lib/translateTextTemplate.test.js +22 -16
  35. package/package.json +4 -4
  36. package/.nyc_output/processinfo/6aec5420-0b83-4260-b300-4d595dfd0660.json +0 -1
  37. package/hugo-renderer/build.sh +0 -66
  38. package/hugo-renderer/deps/bookshop_modified_deps.go +0 -6
  39. package/hugo-renderer/go.mod +0 -19
  40. package/hugo-renderer/helpers/bookshop_modified_content.go +0 -98
  41. package/hugo-renderer/helpers/bookshop_modified_general.go +0 -33
  42. package/hugo-renderer/helpers/emoji.go +0 -96
  43. package/hugo-renderer/hugo_renderer.wasm +0 -0
  44. package/hugo-renderer/hugo_renderer.wasm.gz +0 -0
  45. package/hugo-renderer/main.go +0 -42
  46. package/hugo-renderer/tpl/bookshop_engine/bookshop_func_importer.go +0 -35
  47. package/hugo-renderer/tpl/bookshop_engine/bookshop_render.go +0 -64
  48. package/hugo-renderer/tpl/bookshop_library/bookshop_components.go +0 -129
  49. package/hugo-renderer/tpl/bookshop_library/bookshop_data.go +0 -53
  50. package/hugo-renderer/tpl/cast/cast.go +0 -63
  51. package/hugo-renderer/tpl/cast/init.go +0 -57
  52. package/hugo-renderer/tpl/collections/append.go +0 -37
  53. package/hugo-renderer/tpl/collections/apply.go +0 -131
  54. package/hugo-renderer/tpl/collections/collections.go +0 -768
  55. package/hugo-renderer/tpl/collections/complement.go +0 -55
  56. package/hugo-renderer/tpl/collections/index.go +0 -133
  57. package/hugo-renderer/tpl/collections/init.go +0 -214
  58. package/hugo-renderer/tpl/collections/merge.go +0 -126
  59. package/hugo-renderer/tpl/collections/reflect_helpers.go +0 -216
  60. package/hugo-renderer/tpl/collections/sort.go +0 -183
  61. package/hugo-renderer/tpl/collections/symdiff.go +0 -68
  62. package/hugo-renderer/tpl/collections/where.go +0 -517
  63. package/hugo-renderer/tpl/compare/compare.go +0 -324
  64. package/hugo-renderer/tpl/compare/init.go +0 -85
  65. package/hugo-renderer/tpl/crypto/crypto.go +0 -109
  66. package/hugo-renderer/tpl/crypto/init.go +0 -65
  67. package/hugo-renderer/tpl/debug/debug.go +0 -40
  68. package/hugo-renderer/tpl/debug/init.go +0 -45
  69. package/hugo-renderer/tpl/encoding/encoding.go +0 -90
  70. package/hugo-renderer/tpl/encoding/init.go +0 -59
  71. package/hugo-renderer/tpl/fmt/fmt.go +0 -66
  72. package/hugo-renderer/tpl/fmt/init.go +0 -77
  73. package/hugo-renderer/tpl/inflect/inflect.go +0 -79
  74. package/hugo-renderer/tpl/inflect/init.go +0 -60
  75. package/hugo-renderer/tpl/internal/bookshop_modified_templatefuncsRegistry.go +0 -88
  76. package/hugo-renderer/tpl/math/init.go +0 -134
  77. package/hugo-renderer/tpl/math/math.go +0 -164
  78. package/hugo-renderer/tpl/math/round.go +0 -61
  79. package/hugo-renderer/tpl/partials/init.go +0 -55
  80. package/hugo-renderer/tpl/partials/partials.go +0 -88
  81. package/hugo-renderer/tpl/path/init.go +0 -60
  82. package/hugo-renderer/tpl/path/path.go +0 -159
  83. package/hugo-renderer/tpl/reflect/init.go +0 -51
  84. package/hugo-renderer/tpl/reflect/reflect.go +0 -36
  85. package/hugo-renderer/tpl/safe/init.go +0 -80
  86. package/hugo-renderer/tpl/safe/safe.go +0 -72
  87. package/hugo-renderer/tpl/site/bookshop_site.go +0 -67
  88. package/hugo-renderer/tpl/site/init.go +0 -41
  89. package/hugo-renderer/tpl/strings/init.go +0 -229
  90. package/hugo-renderer/tpl/strings/regexp.go +0 -125
  91. package/hugo-renderer/tpl/strings/strings.go +0 -500
  92. package/hugo-renderer/tpl/strings/truncate.go +0 -157
  93. package/hugo-renderer/tpl/transform/bookshop_unmarshal.go +0 -39
  94. package/hugo-renderer/tpl/transform/init.go +0 -113
  95. package/hugo-renderer/tpl/transform/transform.go +0 -116
  96. package/hugo-renderer/update-from-hugo.sh +0 -19
@@ -0,0 +1,215 @@
1
+ // Copyright 2015 The Hugo Authors. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+
14
+ package main
15
+
16
+ import (
17
+ "encoding/json"
18
+ "fmt"
19
+ "io/ioutil"
20
+ "log"
21
+ "path/filepath"
22
+ "syscall/js"
23
+
24
+ "github.com/fsnotify/fsnotify"
25
+ "github.com/gohugoio/hugo/config"
26
+ "github.com/gohugoio/hugo/deps"
27
+ "github.com/gohugoio/hugo/hugofs"
28
+ "github.com/gohugoio/hugo/hugolib"
29
+ "github.com/spf13/afero"
30
+ )
31
+
32
+ type bookshopSiteBuilder struct {
33
+ Cfg config.Provider
34
+ Fs *hugofs.Fs
35
+ Sites *hugolib.HugoSites
36
+ changedFiles []string
37
+ }
38
+
39
+ // Load whatever source config file we have previously written to disk
40
+ func (builder *bookshopSiteBuilder) LoadConfig() error {
41
+ cfg, _, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{
42
+ WorkingDir: "",
43
+ Fs: builder.Fs.Source,
44
+ Filename: "config.toml",
45
+ }, func(cfg config.Provider) error {
46
+ return nil
47
+ })
48
+ if err != nil {
49
+ return err
50
+ }
51
+
52
+ builder.Cfg = cfg
53
+
54
+ return nil
55
+ }
56
+
57
+ // Create our Hugo sites
58
+ // TODO: I don't know how the lang aspects of Hugo
59
+ // will interact with Hugo.
60
+ func (builder *bookshopSiteBuilder) CreateSites() error {
61
+ if err := builder.LoadConfig(); err != nil {
62
+ fmt.Println(fmt.Sprintf("failed to load config: %s", err))
63
+ return fmt.Errorf("failed to load config: %w", err)
64
+ }
65
+
66
+ builder.Fs.PublishDir = hugofs.NewCreateCountingFs(builder.Fs.PublishDir)
67
+
68
+ sites, err := hugolib.NewHugoSites(deps.DepsCfg{
69
+ Fs: builder.Fs,
70
+ Cfg: builder.Cfg,
71
+ Running: true,
72
+ })
73
+ if err != nil {
74
+ fmt.Println(fmt.Sprintf("failed to create sites: %s", err))
75
+ return fmt.Errorf("failed to create sites: %w", err)
76
+ }
77
+ builder.Sites = sites
78
+
79
+ return nil
80
+ }
81
+
82
+ // Runs a standard Hugo build into our in-memory "public" directory
83
+ func (builder *bookshopSiteBuilder) build(cfg hugolib.BuildCfg) error {
84
+ if builder.Sites == nil {
85
+ builder.CreateSites()
86
+ }
87
+
88
+ err := builder.Sites.Build(cfg, builder.changeEvents()...)
89
+
90
+ if err == nil {
91
+ logErrorCount := builder.Sites.NumLogErrors()
92
+ if logErrorCount > 0 {
93
+ err = fmt.Errorf("logged %d errors", logErrorCount)
94
+ }
95
+ }
96
+ if err != nil {
97
+ fmt.Errorf("Build failed: %s", err)
98
+ fmt.Println(fmt.Sprintf("Build failed: %s", err))
99
+ return err
100
+ }
101
+ return nil
102
+ }
103
+
104
+ // Writes content to the given file path in the in-memory filesystem
105
+ func (builder *bookshopSiteBuilder) writeFile(filename, content string) {
106
+ if err := afero.WriteFile(builder.Fs.Source, filepath.FromSlash(filename), []byte(content), 0755); err != nil {
107
+ fmt.Println(fmt.Sprintf("Failed to write file: %s", err))
108
+ }
109
+
110
+ builder.changedFiles = append(builder.changedFiles, filename)
111
+ }
112
+
113
+ // Reads content from the given file path in the in-memory filesystem
114
+ func (builder *bookshopSiteBuilder) readFile(filename string) string {
115
+ b, err := afero.ReadFile(builder.Fs.Source, filepath.Clean(filename))
116
+ if err != nil {
117
+ fmt.Println(fmt.Sprintf("Failed to read file: %s", err))
118
+ }
119
+ return string(b)
120
+ }
121
+
122
+ // Helper method to list out any files in our virtual fs
123
+ func (builder *bookshopSiteBuilder) debugDir(dir string) {
124
+ files, err := afero.ReadDir(builder.Fs.Source, dir)
125
+ if err == nil {
126
+ for _, file := range files {
127
+ fmt.Println(fmt.Sprintf("%s > %+v", dir, file.Name()))
128
+ }
129
+ } else {
130
+ fmt.Println(fmt.Sprintf("Error debugging directory: %+v", err))
131
+ }
132
+ }
133
+
134
+ func (builder *bookshopSiteBuilder) changeEvents() []fsnotify.Event {
135
+ var events []fsnotify.Event
136
+
137
+ for _, v := range builder.changedFiles {
138
+ events = append(events, fsnotify.Event{
139
+ Name: v,
140
+ Op: fsnotify.Write,
141
+ })
142
+ }
143
+
144
+ return events
145
+ }
146
+
147
+ var builder bookshopSiteBuilder
148
+ var build_config hugolib.BuildCfg
149
+
150
+ func main() {
151
+ fs_config := config.NewWithTestDefaults()
152
+ fs := hugofs.NewMem(fs_config)
153
+ builder = bookshopSiteBuilder{Fs: fs}
154
+ build_config = hugolib.BuildCfg{
155
+ NoBuildLock: true,
156
+ }
157
+
158
+ log.SetOutput(ioutil.Discard)
159
+
160
+ c := make(chan struct{}, 0)
161
+ js.Global().Set("initHugoConfig", js.FuncOf(initHugoConfig))
162
+ js.Global().Set("writeHugoFiles", js.FuncOf(writeHugoFiles))
163
+ js.Global().Set("readHugoFiles", js.FuncOf(readHugoFiles))
164
+ js.Global().Set("buildHugo", js.FuncOf(buildHugo))
165
+ <-c
166
+ }
167
+
168
+ func initHugoConfig(this js.Value, args []js.Value) interface{} {
169
+ if err := builder.LoadConfig(); err != nil {
170
+ fmt.Println(fmt.Sprintf("failed to load config: %s", err))
171
+ return fmt.Errorf("failed to load config: %w", err)
172
+ }
173
+ if err := builder.CreateSites(); err != nil {
174
+ fmt.Println(fmt.Sprintf("failed to create sites: %s", err))
175
+ return fmt.Errorf("failed to create sites: %w", err)
176
+ }
177
+ return nil
178
+ }
179
+
180
+ func writeHugoFiles(this js.Value, args []js.Value) interface{} {
181
+ var writeFiles map[string]string
182
+ err := json.Unmarshal([]byte(args[0].String()), &writeFiles)
183
+ if err != nil {
184
+ fmt.Println(fmt.Sprintf("Bad json: %+v", err))
185
+ return nil
186
+ }
187
+
188
+ for file_name, file_contents := range writeFiles {
189
+ builder.writeFile(file_name, file_contents)
190
+ }
191
+ return nil
192
+ }
193
+
194
+ func readHugoFiles(this js.Value, args []js.Value) interface{} {
195
+ var readFiles []string
196
+ err := json.Unmarshal([]byte(args[0].String()), &readFiles)
197
+ if err != nil {
198
+ fmt.Println(fmt.Sprintf("Bad json: %+v", err))
199
+ return nil
200
+ }
201
+
202
+ fileContents := make(map[string]interface{})
203
+ for _, file_name := range readFiles {
204
+ fileContents[file_name] = builder.readFile(file_name)
205
+ }
206
+
207
+ return js.ValueOf(fileContents)
208
+ }
209
+
210
+ func buildHugo(this js.Value, args []js.Value) interface{} {
211
+ if err := builder.build(build_config); err != nil {
212
+ return fmt.Sprintf("Build error: %+v", err)
213
+ }
214
+ return nil
215
+ }
@@ -48,7 +48,10 @@
48
48
  outputBuf += decoder.decode(buf);
49
49
  const nl = outputBuf.lastIndexOf("\n");
50
50
  if (nl != -1) {
51
- console.log(outputBuf.substr(0, nl));
51
+ // Disable all logs from the WASM side
52
+ if (window.log_hugo_wasm) {
53
+ console.log(outputBuf.substr(0, nl));
54
+ }
52
55
  outputBuf = outputBuf.substr(nl + 1);
53
56
  }
54
57
  return buf.length;
@@ -499,7 +502,8 @@
499
502
  },
500
503
 
501
504
  "debug": (value) => {
502
- console.log(value);
505
+ // Disable all logs from the WASM side
506
+ // console.log(value);
503
507
  },
504
508
  }
505
509
  };
package/lib/builder.js CHANGED
@@ -9,12 +9,12 @@ export const extensions = [".hugo.html"];
9
9
  export const esbuildConfigFn = (esbuildConfig, options) => {
10
10
  esbuildConfig.loader = {
11
11
  ...esbuildConfig.loader,
12
+ ".html": "text",
12
13
  ".hugo.html": "text",
13
- ".wasm": options?.hosted ? "file" : "binary",
14
14
  ".wasm.gz": options?.hosted ? "file" : "binary",
15
15
  };
16
16
 
17
- const wasm_exec_banner = fs.readFileSync(path.join(__dirname, "../hugo-renderer/wasm_exec.js"));
17
+ const wasm_exec_banner = fs.readFileSync(path.join(__dirname, "../full-hugo-renderer/wasm_exec.js"));
18
18
  esbuildConfig.banner = {
19
19
  ...esbuildConfig.banner,
20
20
  js: (esbuildConfig.js ?? "") + wasm_exec_banner
package/lib/engine.js CHANGED
@@ -1,5 +1,4 @@
1
- import hugoWasm from "../hugo-renderer/hugo_renderer.wasm";
2
- import compressedHugoWasm from "../hugo-renderer/hugo_renderer.wasm.gz";
1
+ import compressedHugoWasm from "../full-hugo-renderer/hugo_renderer.wasm.gz";
3
2
  import { gunzipSync } from 'fflate';
4
3
  import translateTextTemplate from './translateTextTemplate.js';
5
4
  import { IdentifierParser } from './hugoIdentifierParser.js';
@@ -33,8 +32,24 @@ export class Engine {
33
32
  }
34
33
 
35
34
  async initializeHugo() {
35
+ const templates = {
36
+ "layouts/partials/bookshop.html": (await import("../bookshop-hugo-templates/bookshop.html")).default,
37
+ "layouts/partials/bookshop_scss.html": (await import("../bookshop-hugo-templates/bookshop_scss.html")).default,
38
+ "layouts/partials/bookshop_partial.html": (await import("../bookshop-hugo-templates/bookshop_partial.html")).default,
39
+ "layouts/partials/bookshop_component_browser.html": (await import("../bookshop-hugo-templates/bookshop_component_browser.html")).default,
40
+ "layouts/partials/bookshop_bindings.html": (await import("../bookshop-hugo-templates/bookshop_bindings.html")).default,
41
+ "layouts/partials/_bookshop/helpers/component.html": (await import("../bookshop-hugo-templates/helpers/component.html")).default,
42
+ "layouts/partials/_bookshop/helpers/component_key.html": (await import("../bookshop-hugo-templates/helpers/component_key.html")).default,
43
+ "layouts/partials/_bookshop/helpers/partial.html": (await import("../bookshop-hugo-templates/helpers/partial.html")).default,
44
+ "layouts/partials/_bookshop/helpers/partial_key.html": (await import("../bookshop-hugo-templates/helpers/partial_key.html")).default,
45
+ "layouts/partials/_bookshop/errors/bad_bookshop_tag.html": (await import("../bookshop-hugo-templates/errors/bad_bookshop_tag.html")).default,
46
+ "layouts/partials/_bookshop/errors/err.html": (await import("../bookshop-hugo-templates/errors/err.html")).default,
47
+ };
48
+
49
+ templates["config.toml"] = "params.env_bookshop_live = true";
50
+
36
51
  // When this script is run locally, the hugo wasm is loaded as binary rather than output as a file.
37
- if (hugoWasm?.constructor === Uint8Array) {
52
+ if (compressedHugoWasm?.constructor === Uint8Array) {
38
53
  await this.initializeInlineHugo();
39
54
  } else {
40
55
  await this.initializeLocalCompressedHugo();
@@ -43,12 +58,11 @@ export class Engine {
43
58
  // TODO: Tidy
44
59
  const mappedFiles = {};
45
60
  for (const file of Object.entries(this.files)) {
46
- mappedFiles[file[0]] = {
47
- contents: translateTextTemplate(file[1], {})
48
- }
61
+ mappedFiles[`layouts/partials/bookshop/${file[0]}`] = translateTextTemplate(file[1], {});
49
62
  }
50
63
 
51
- const success = window.loadHugoBookshopPartials(JSON.stringify(mappedFiles));
64
+ const componentSuccess = window["writeHugoFiles"](JSON.stringify(mappedFiles));
65
+ const templateSuccess = window["writeHugoFiles"](JSON.stringify(templates));
52
66
  }
53
67
 
54
68
  async initializeLocalCompressedHugo() {
@@ -66,28 +80,25 @@ export class Engine {
66
80
  const compressedResult = await WebAssembly.instantiate(renderer, go.importObject);
67
81
  go.run(compressedResult.instance);
68
82
  } catch (e) {
69
- await this.initializeLocalHugo();
83
+ console.error("Couldn't load the local compressed Hugo WASM");
84
+ console.error(e);
70
85
  }
71
86
  }
72
87
 
73
- async initializeLocalHugo() {
88
+ async initializeInlineHugo() {
74
89
  const go = new Go();
75
- const wasmOrigin = this.origin.replace(/\/[^\.\/]+\.(min\.)?js/, hugoWasm.replace(/^\./, ''));
76
- const response = await fetch(wasmOrigin);
77
- const buffer = await response.arrayBuffer();
78
- const result = await WebAssembly.instantiate(buffer, go.importObject);
90
+ const buffer = compressedHugoWasm.buffer;
91
+ const renderer = gunzipSync(new Uint8Array(buffer));
92
+ const result = await WebAssembly.instantiate(renderer, go.importObject);
79
93
  go.run(result.instance);
80
94
  }
81
95
 
82
- async initializeInlineHugo() {
83
- const go = new Go();
84
- const buffer = hugoWasm.buffer;
85
- const result = await WebAssembly.instantiate(buffer, go.importObject);
86
- go.run(result.instance);
96
+ getSharedKey(name) {
97
+ return `shared/hugo/${name}.hugo.html`;
87
98
  }
88
99
 
89
100
  getShared(name) {
90
- const key = `shared/hugo/${name}.hugo.html`
101
+ const key = this.getSharedKey(name);
91
102
  return this.files?.[key];
92
103
  }
93
104
 
@@ -106,9 +117,14 @@ export class Engine {
106
117
  return !!this.files?.[key];
107
118
  }
108
119
 
120
+ hasShared(name) {
121
+ const key = this.getSharedKey(name);
122
+ return !!this.files?.[key];
123
+ }
124
+
109
125
  resolveComponentType(name) {
110
- if (this.getComponent(name)) return 'component';
111
- if (this.getShared(name)) return 'shared';
126
+ if (this.hasComponent(name)) return 'component';
127
+ if (this.hasShared(name)) return 'shared';
112
128
  return false;
113
129
  }
114
130
 
@@ -119,38 +135,58 @@ export class Engine {
119
135
  }
120
136
 
121
137
  async storeMeta(meta = {}) {
122
- while (!window.loadHugoBookshopMeta) {
138
+ while (!window.writeHugoFiles) {
123
139
  await sleep(100);
124
140
  };
125
- window.loadHugoBookshopMeta(JSON.stringify(meta));
141
+ window.writeHugoFiles(JSON.stringify({
142
+ "config.toml": [
143
+ meta.baseurl ? `baseURL = ${meta.baseurl}` : "",
144
+ meta.copyright ? `copyright = ${meta.copyright}` : "",
145
+ meta.title ? `title = ${meta.title}` : "",
146
+ "params.env_bookshop_live = true"
147
+ ].join('\n')
148
+ }));
149
+ const err = window.initHugoConfig();
150
+ if (err) {
151
+ console.error(err);
152
+ }
153
+
154
+ // window.loadHugoBookshopMeta(JSON.stringify(meta));
126
155
  }
127
156
 
128
157
  async storeInfo(info = {}) {
129
- while (!window.loadHugoBookshopData) {
158
+ while (!window.writeHugoFiles) {
130
159
  await sleep(100);
131
160
  };
132
- window.loadHugoBookshopData(JSON.stringify(info));
161
+
162
+ const data = info?.data;
163
+ if (!data || typeof data !== "object") return;
164
+ const files = {};
165
+ for (const [file, contents] of Object.entries(data)) {
166
+ files[`data/${file}.json`] = JSON.stringify(contents);
167
+ }
168
+ window.writeHugoFiles(JSON.stringify(files));
133
169
  }
134
170
 
135
171
  async render(target, name, props, globals, logger) {
136
- while (!window.renderHugo) {
172
+ while (!window.buildHugo) {
137
173
  logger?.log?.(`Waiting for the Hugo WASM to be available...`);
138
174
  await sleep(100);
139
175
  };
140
176
 
141
- let source = this.getComponent(name);
142
- // TODO: Remove the below check and update the live comments to denote shared
143
- if (!source) source = this.getShared(name);
144
- if (!source) {
177
+ let writeFiles = {};
178
+
179
+ if (this.hasComponent(name)) {
180
+ writeFiles["layouts/index.html"] = `{{ partial "bookshop" (slice "${name}" .Params.component) }}`
181
+ } else if (this.hasShared(name)) {
182
+ writeFiles["layouts/index.html"] = `{{ partial "bookshop_partial" (slice "${name}" .Params.component) }}`
183
+ } else {
145
184
  console.warn(`[hugo-engine] No component found for ${name}`);
146
185
  return "";
147
186
  }
148
- logger?.log?.(`Going to render ${name}, with source:`);
149
- logger?.log?.(source);
150
- // TODO: this template already exists on the other side of the wasm bounary
151
- source = translateTextTemplate(source, {});
152
- logger?.log?.(`Rewritten the template for ${name} to:`);
153
- logger?.log?.(source);
187
+ logger?.log?.(`Going to render ${name}, with layout:`);
188
+ logger?.log?.(writeFiles["layouts/index.html"]);
189
+
154
190
  if (!globals || typeof globals !== "object") globals = {};
155
191
  props = {
156
192
  ...globals, ...props,
@@ -159,7 +195,25 @@ export class Engine {
159
195
 
160
196
  // If we have assigned a root scope we need to pass that in as the context
161
197
  if (props["."]) props = props["."];
162
- const output = window.renderHugo(source, JSON.stringify(props));
198
+ writeFiles["content/_index.md"] = JSON.stringify({
199
+ component: props
200
+ }, null, 2) + "\n";
201
+ window.writeHugoFiles(JSON.stringify(writeFiles));
202
+
203
+ const buildResult = window.buildHugo();
204
+ if (buildResult) {
205
+ console.error(buildResult);
206
+ return;
207
+ }
208
+
209
+ const output = window.readHugoFiles(JSON.stringify([
210
+ "public/index.html"
211
+ ]));
212
+
213
+ target.innerHTML = output["public/index.html"];
214
+ return;
215
+
216
+ const outputs = window.renderHugo(source, JSON.stringify(props));
163
217
  if (/BKSHERR/.test(output)) {
164
218
  logger?.log?.(`Failed to render ${output}`);
165
219
  console.error(output);
@@ -171,7 +225,7 @@ export class Engine {
171
225
  }
172
226
 
173
227
  async eval(str, props = [{}]) {
174
- while (!window.renderHugo) await sleep(10);
228
+ while (!window.buildHugo) await sleep(10);
175
229
  let props_obj = props.reduce((a, b) => { return { ...a, ...b } });
176
230
 
177
231
  // We're capable of looking up a simple variable
@@ -190,15 +244,28 @@ export class Engine {
190
244
 
191
245
  const assignments = Object.entries(props_obj).filter(([key]) => key.startsWith('$')).map(([key, value]) => {
192
246
  if (Array.isArray(value)) {
193
- return `{{ ${key} := index ( \`{"a": ${JSON.stringify(value)}}\` | transform.BookshopUnmarshal ) "a" }}`
247
+ return `{{ ${key} := index ( \`{"a": ${JSON.stringify(value)}}\` | transform.Unmarshal ) "a" }}`
194
248
  } else if (typeof value === 'object') {
195
- return `{{ ${key} := \`${JSON.stringify(value)}\` | transform.BookshopUnmarshal }}`
249
+ return `{{ ${key} := \`${JSON.stringify(value)}\` | transform.Unmarshal }}`
196
250
  } else {
197
251
  return `{{ ${key} := ${JSON.stringify(value)} }}`
198
252
  }
199
253
  }).join('');
200
- const eval_str = `${assignments}{{ jsonify (${str}) }}`;
201
- const output = window.renderHugo(eval_str, JSON.stringify(props_obj));
254
+ const eval_str = `{{ with .Params.props }}${assignments}{{ jsonify (${str}) }}{{ end }}`;
255
+ window.writeHugoFiles(JSON.stringify({
256
+ "layouts/index.html": eval_str,
257
+ "content/_index.md": JSON.stringify({ props: props_obj }, null, 2)
258
+ }));
259
+
260
+ const buildError = window.buildHugo();
261
+ if (buildError) {
262
+ console.warn(buildError);
263
+ return;
264
+ }
265
+
266
+ const output = window.readHugoFiles(JSON.stringify([
267
+ "public/index.html"
268
+ ]))["public/index.html"];
202
269
 
203
270
  try {
204
271
  return JSON.parse(output);
@@ -36,6 +36,11 @@ export class IdentifierParser {
36
36
  return `${variable}.${index}`;
37
37
  }
38
38
 
39
+ // strip the leading .Params. from basic variable references
40
+ // if (/^\s*\./.test(this.input)) {
41
+ // return this.input.replace(/^\s*\.Params\.([^\.\s])/, '$1');
42
+ // }
43
+
39
44
  // strip the leading . from basic variable references
40
45
  if (/^\s*\./.test(this.input)) {
41
46
  return this.input.replace(/^\s*\.([^\.\s])/, '$1');
@@ -105,6 +105,9 @@ export default function (text, opts) {
105
105
  liveMarkup: true,
106
106
  ...opts
107
107
  }
108
+ if (!/bookshop/.test(text)) {
109
+ return text;
110
+ }
108
111
  const tokenizer = new Tokenizer(text.toString());
109
112
  const tokens = tokenizer.readTopLevelTokens();
110
113
  const output = [];
@@ -28,34 +28,40 @@ test("don't add live markup to bookshop_partial tags", t => {
28
28
  t.is(translateTextTemplate(input, {}), expected);
29
29
  });
30
30
 
31
- test("add live markup to assigns", t => {
31
+ test("don't add live markup if no bookshop found", t => {
32
32
  let input = `{{ $a := .b }}`;
33
- let expected = `{{ $a := .b }}{{ \`<!--bookshop-live context($a: (.b))-->\` | safeHTML }}`;
33
+ let expected = `{{ $a := .b }}`;
34
34
  t.is(translateTextTemplate(input, {}), expected);
35
+ });
35
36
 
36
- input = `{{ $a := .b | chomp }}`;
37
- expected = `{{ $a := .b | chomp }}{{ \`<!--bookshop-live context($a: (.b | chomp))-->\` | safeHTML }}`;
37
+ test("add live markup to assigns", t => {
38
+ let input = `{{ $a := .b }}bookshop`;
39
+ let expected = `{{ $a := .b }}{{ \`<!--bookshop-live context($a: (.b))-->\` | safeHTML }}bookshop`;
38
40
  t.is(translateTextTemplate(input, {}), expected);
39
41
 
40
- input = `{{ $a = .b }}`;
41
- expected = `{{ $a = .b }}{{ \`<!--bookshop-live reassign($a: (.b))-->\` | safeHTML }}`;
42
+ input = `{{ $a := .b | chomp }}bookshop`;
43
+ expected = `{{ $a := .b | chomp }}{{ \`<!--bookshop-live context($a: (.b | chomp))-->\` | safeHTML }}bookshop`;
44
+ t.is(translateTextTemplate(input, {}), expected);
45
+
46
+ input = `{{ $a = .b }}bookshop`;
47
+ expected = `{{ $a = .b }}{{ \`<!--bookshop-live reassign($a: (.b))-->\` | safeHTML }}bookshop`;
42
48
  t.is(translateTextTemplate(input, {}), expected);
43
49
  });
44
50
 
45
51
  test("add live markup to withs", t => {
46
- const input = `{{ with .b }}<p>{{.}}</p>{{ end }}`;
52
+ const input = `{{ with .b }}<p>{{.}}</p>{{ end }}bookshop`;
47
53
  const expected = [`{{ with .b }}`,
48
54
  `{{ \`<!--bookshop-live stack-->\` | safeHTML }}`,
49
55
  `{{ \`<!--bookshop-live context(.: (.b))-->\` | safeHTML }}`,
50
56
  `<p>{{.}}</p>`,
51
57
  `{{ \`<!--bookshop-live unstack-->\` | safeHTML }}`,
52
- `{{ end }}`
58
+ `{{ end }}bookshop`
53
59
  ].join('');
54
60
  t.is(translateTextTemplate(input, {}), expected);
55
61
  });
56
62
 
57
63
  test("add live markup to loops", t => {
58
- const input = `{{ range .items }}<p>{{ . }}</p>{{ end }}`;
64
+ const input = `{{ range .items }}<p>{{ . }}</p>{{ end }}bookshop`;
59
65
  const expected = [`{{ $bookshop__live__iterator__keys := (slice) }}`,
60
66
  `{{ range $i, $e := (.items) }}{{ $bookshop__live__iterator__keys = $bookshop__live__iterator__keys | append $i }}{{ end }}`,
61
67
  `{{ $bookshop__live__iterator := 0 }}`,
@@ -66,26 +72,26 @@ test("add live markup to loops", t => {
66
72
  `{{ $bookshop__live__iterator = (add $bookshop__live__iterator 1) }}`,
67
73
  `<p>{{ . }}</p>`,
68
74
  `{{ \`<!--bookshop-live unstack-->\` | safeHTML }}`,
69
- `{{ end }}`
75
+ `{{ end }}bookshop`
70
76
  ].join('');
71
77
  t.is(translateTextTemplate(input, {}), expected);
72
78
  });
73
79
 
74
80
  test("add live markup to loops with iterators", t => {
75
- const input = `{{range $loop_index, $element := .columns}}<p>{{$element}}</p>{{ end }}`;
81
+ const input = `{{range $loop_index, $element := .columns}}<p>{{$element}}</p>{{ end }}bookshop`;
76
82
  const expected = [`{{range $loop_index, $element := .columns}}`,
77
83
  `{{ \`<!--bookshop-live stack-->\` | safeHTML }}`,
78
84
  `{{ (printf \`<!--bookshop-live context(.: (index (.columns) %v))-->\` (jsonify $loop_index)) | safeHTML }}`,
79
85
  `<p>{{$element}}</p>`,
80
86
  `{{ \`<!--bookshop-live unstack-->\` | safeHTML }}`,
81
- `{{ end }}`
87
+ `{{ end }}bookshop`
82
88
  ].join('');
83
89
  t.is(translateTextTemplate(input, {}), expected);
84
90
  });
85
91
 
86
92
  test("escape backticks in values", t => {
87
- let input = `{{ $a := "hi\`:)" }}`;
88
- let expected = `{{ $a := "hi\`:)" }}{{ replace \`<!--bookshop-live context($a: ("hiBKSH_BACKTICK:)"))-->\` "BKSH_BACKTICK" "\`" | safeHTML }}`;
93
+ let input = `{{ $a := "hi\`:)" }}bookshop`;
94
+ let expected = `{{ $a := "hi\`:)" }}{{ replace \`<!--bookshop-live context($a: ("hiBKSH_BACKTICK:)"))-->\` "BKSH_BACKTICK" "\`" | safeHTML }}bookshop`;
89
95
  t.is(translateTextTemplate(input, {}), expected);
90
96
  });
91
97
 
@@ -105,7 +111,7 @@ test("add live markup to complex end structures", t => {
105
111
  {{end}}
106
112
  {{ end }}
107
113
 
108
- {{ end }}`;
114
+ {{ end }}bookshop`;
109
115
  const expected = `
110
116
  {{ $bookshop__live__iterator__keys := (slice) }}{{ range $i, $e := (.items) }}{{ $bookshop__live__iterator__keys = $bookshop__live__iterator__keys | append $i }}{{ end }}{{ $bookshop__live__iterator := 0 }}{{ range .items }}{{ \`<!--bookshop-live stack-->\` | safeHTML }}{{ $bookshop__live__iterator__key := (index ($bookshop__live__iterator__keys) $bookshop__live__iterator) }}{{ (printf \`<!--bookshop-live context(.: (index (.items) %v))-->\` (jsonify $bookshop__live__iterator__key)) | safeHTML }}{{ $bookshop__live__iterator = (add $bookshop__live__iterator 1) }}
111
117
 
@@ -121,7 +127,7 @@ test("add live markup to complex end structures", t => {
121
127
  {{ \`<!--bookshop-live unstack-->\` | safeHTML }}{{end}}
122
128
  {{ end }}
123
129
 
124
- {{ \`<!--bookshop-live unstack-->\` | safeHTML }}{{ end }}`;
130
+ {{ \`<!--bookshop-live unstack-->\` | safeHTML }}{{ end }}bookshop`;
125
131
  t.is(translateTextTemplate(input, {}), expected);
126
132
  });
127
133
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bookshop/hugo-engine",
3
3
  "packageManager": "yarn@3.0.0",
4
- "version": "3.3.2",
4
+ "version": "3.4.0-alpha.2",
5
5
  "description": "Bookshop frontend Hugo renderer",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -14,8 +14,8 @@
14
14
  "*.js",
15
15
  "lib/*.js",
16
16
  "!**/*.test.js",
17
- "hugo-renderer/hugo_renderer.wasm",
18
- "hugo-renderer/hugo_renderer.wasm.gz"
17
+ "full-hugo-renderer/hugo_renderer.wasm.gz",
18
+ "bookshop-hugo-templates/**/*"
19
19
  ],
20
20
  "scripts": {
21
21
  "test": "nyc ava -v"
@@ -30,7 +30,7 @@
30
30
  "nyc": "^15.1.0"
31
31
  },
32
32
  "dependencies": {
33
- "@bookshop/helpers": "3.3.2",
33
+ "@bookshop/helpers": "3.4.0-alpha.2",
34
34
  "esbuild": "^0.13.10",
35
35
  "fflate": "^0.7.3",
36
36
  "liquidjs": "9.28.0"
@@ -1 +0,0 @@
1
- {"parent":null,"pid":3424,"argv":["/opt/hostedtoolcache/node/16.18.1/x64/bin/node","/home/runner/work/bookshop/bookshop/javascript-modules/node_modules/ava/cli.js","-v"],"execArgv":[],"cwd":"/home/runner/work/bookshop/bookshop/javascript-modules/engines/hugo-engine","time":1669766790333,"ppid":3413,"coverageFilename":"/home/runner/work/bookshop/bookshop/javascript-modules/engines/hugo-engine/.nyc_output/6aec5420-0b83-4260-b300-4d595dfd0660.json","externalId":"","uuid":"6aec5420-0b83-4260-b300-4d595dfd0660","files":[]}