@kenjura/ursa 0.76.0 → 0.78.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 (35) hide show
  1. package/CHANGELOG.md +41 -17
  2. package/README.md +1 -1
  3. package/meta/default.css +33 -0
  4. package/meta/templates/default-template/default.css +1268 -0
  5. package/meta/{default-template.html → templates/default-template/index.html} +15 -0
  6. package/meta/{menu.js → templates/default-template/menu.js} +1 -1
  7. package/meta/templates/default-template/sectionify.js +46 -0
  8. package/meta/{widgets.js → templates/default-template/widgets.js} +126 -0
  9. package/package.json +4 -2
  10. package/src/dev.js +73 -28
  11. package/src/helper/assetBundler.js +471 -0
  12. package/src/helper/build/autoIndex.js +24 -23
  13. package/src/helper/build/cacheBust.js +79 -0
  14. package/src/helper/build/navCache.js +4 -0
  15. package/src/helper/build/templates.js +176 -19
  16. package/src/helper/build/watchCache.js +7 -0
  17. package/src/helper/customMenu.js +4 -2
  18. package/src/helper/dependencyTracker.js +269 -0
  19. package/src/helper/findStyleCss.js +29 -0
  20. package/src/helper/portUtils.js +132 -0
  21. package/src/jobs/generate.js +234 -62
  22. package/src/serve.js +446 -162
  23. package/meta/character-sheet.css +0 -50
  24. /package/meta/{goudy_bookletter_1911-webfont.woff → shared/goudy_bookletter_1911-webfont.woff} +0 -0
  25. /package/meta/{character-sheet/css → templates/character-sheet-template}/character-sheet.css +0 -0
  26. /package/meta/{character-sheet/js → templates/character-sheet-template}/components.js +0 -0
  27. /package/meta/{cssui.bundle.min.css → templates/character-sheet-template/cssui.bundle.min.css} +0 -0
  28. /package/meta/{character-sheet-template.html → templates/character-sheet-template/index.html} +0 -0
  29. /package/meta/{character-sheet/js → templates/character-sheet-template}/main.js +0 -0
  30. /package/meta/{character-sheet/js → templates/character-sheet-template}/model.js +0 -0
  31. /package/meta/{search.js → templates/default-template/search.js} +0 -0
  32. /package/meta/{sticky.js → templates/default-template/sticky.js} +0 -0
  33. /package/meta/{toc-generator.js → templates/default-template/toc-generator.js} +0 -0
  34. /package/meta/{toc.js → templates/default-template/toc.js} +0 -0
  35. /package/meta/{template2.html → templates/template2/index.html} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,21 +1,25 @@
1
- # 0.77.0 (TODO)
1
+ # 0.78.0
2
+ 2026-02-13
3
+
4
+ - added release-it
5
+ - --clean now fully deletes the .ursa cache folder and clears the output directory before generation, ensuring a completely fresh build without any stale files. Previously, --clean only ignored the cache but left existing output files in place, which could cause issues with stale auto-generated indexes and other files blocking new generation. This change provides a more robust clean build experience.
6
+
7
+ # 0.77.0
8
+ 2026-02-13
2
9
 
3
10
  QOL:
4
11
  - When 'serve' encounters an occupied port 8080, prompt the user to find an available port instead of just exiting with an error. Will check open ports and find the closest port to 8080, then ask the user if they want to use it.
5
12
 
13
+ Meta cleanup:
14
+ - Templates should have their own folder, including default
15
+ - All static files for a template should be in the template's folder, and probably in the right subfolder (e.g. public/default.css should be in templates/default/public/default.css or something like that).
16
+ - Template filenames should be templates/{templateName}/index.html
17
+ - Ursa should throw a warning if it finds orphaned static files in meta that aren't referenced by a template
18
+
6
19
  Static assets revamp:
7
- - Meta
8
- - All scripts and stylesheets referenced by a template should be bundled together into a single CSS file and a single JS file per template. Use esbuild or similar for bundling and minification. This will reduce the number of requests and ensure that all template assets are loaded together.
9
- - Documents
10
- - style.css and script.js files should be external
11
- - in serve mode, a document can have multiple style.css and script.js from multiple levels; this should be separate tags so individual ones can be invalidated
12
- - in generate mode, these should be bundled together into a single CSS file and a single JS file per folder
13
- - why folder? well, /foo may have style.css and script.js, and /foo/bar may have its own style.css and script.js. Every document in foo/bar includes both scripts and both stylesheets, but documents in foo only include the foo ones.
14
- - it is true that foo.bundle.js and foo-bar.bundle.js will duplicate code (foo-bar is a superset of foo), but the point is that every page load has the minimum number of requests (1 CSS and 1 JS)
15
- - future optimization: bundle document and meta scripts/styles together. This sounds complicated compared to the expected return
16
- - Bundling logic:
17
- - In serve mode, minification without obfuscation is fine, as serve is often used to debug stylesheets and scripts.
18
- - In generate mode, we can do full bundling and minification for optimal performance. Map files can be generated for debugging if needed.
20
+ - Revamped the building of static assets (stylesheets and scripts). The new logic is:
21
+ - All meta scripts and stylesheets should be bundled together into a single CSS file and a single JS file for the entire site. This applies to build mode; in dev mode, they are served individually for easier debugging and regeneration.
22
+ - Bundle-able document files (style.css, script.js, menu.md) will be bundled together on a per-folder basis. Each document will include the bundles from its own folder and all parent folders (where they exist).
19
23
 
20
24
  Regeneration revamp:
21
25
  - Existing logic:
@@ -35,6 +39,26 @@ Regeneration revamp:
35
39
  - Find all documents that reference that static file
36
40
  - Regenerate the html (even if the source md/mdx/txt file is unchanged) for those documents to update the cache-busting query string for the static file reference
37
41
  - This should catch all the various edge cases that previously required restarting the server or doing a full regeneration.
42
+ - Regeneration priority order:
43
+ - When regeneration is triggered, check for connected WebSocket clients and get their current URL.
44
+ - If their current URL is affected by the change (document, static asset, template, anything), prioritize the necessary documents and assets to serve that URL before all others, and when they are regenerated, send the push notification to reload.
45
+ - After that, regenerate the rest of the affected documents in the background.
46
+ - In cases of rapid changing of files, do the following:
47
+ - Debounce all file system change events within a short time window (e.g. 500ms); wait for at least 500ms of no changes before starting regeneration. This helps in cases where a script or bot is making many changes to many files.
48
+ - When a change is detected, before any complex processing, send a ping to WebSocket-connected clients that an update is in progress, but it isn't known yet if it will affect their page.
49
+ - When it is determined that a change will affect the current page of a connected client, send another push to let the client know.
50
+ - Handle the above two notifications in the UI thus:
51
+ - When updates start, add a subtle loading indicator to the right of all left widgets, such as <Loader color="gray" />
52
+ - If it turns out the update doesn't need a refresh, remove the indicator.
53
+ - If it does need a refresh, change the indicator to a <Loader color="green" />.
54
+ - When the hot refresh actually happens, the indicator shouldn't be there anymore.
55
+ - Cache changes (under consideration):
56
+ - Before the cache was implemented, every file change triggered a complete regeneration of the entire site. This was slow, obviously. First, an in-memory cache was added to speed up the regeneration of unchanged files. But since the watcher back then missed a lot of regeneration cases (such as all meta changes), killing 'serve' and restarting it was quite common. Thus, the cache was persisted to disk, so that even in the case of a full regeneration (such as after a restart), unchanged files would still be skipped. This has worked fairly well, but for the invalidation edge cases described above (already fixed).
57
+ - However, considering that we now have a robust regeneration system that can handle all edge cases and push updates to the client, we may want to consider removing the cache entirely. The cache adds complexity and can sometimes get into a bad state, requiring manual deletion. With the new regeneration system, we could keep the cache in-memory, and rarely will the user need to kill 'serve' and restart just to get an update (ideally, never). In-memory cache is even faster than disk, so this might be a better experience overall.
58
+ - Regeneration cases still unhandled:
59
+ - User updates Ursa itself (e.g. npm update) while serve is active. I mean, this shouldn't be very common outside of Ursa devs, but's determine:
60
+ - Does the current system actually catch the meta changes?
61
+
38
62
 
39
63
 
40
64
  Top Menu improvements:
@@ -48,10 +72,10 @@ New Widgets:
48
72
  - LLM-guided suggestions based on frequently viewed content, suggested related documents you haven't viewed yet, etc.
49
73
 
50
74
  Bugs:
51
- - [ ] When using menu.md with auto-generation, the top menu's Home href is "//index.html" instead of "/index.html". On localhost, this ends up working fine, but on https://realdomain.com, this loads https://index.html which obviously doesn't work. The current logic seems to prefer absolute URLs, so in this case, the url for home should be "/index.html" (not double slash).
52
- - [ ] Site style.css is not present on auto-generated index pages
53
- - Regeneration issues:
54
- - Create a power, that power page now exists. But powers.json doesn't have it.
75
+ - [x] When using menu.md with auto-generation, the top menu's Home href is "//index.html" instead of "/index.html". On localhost, this ends up working fine, but on https://realdomain.com, this loads https://index.html which obviously doesn't work. The current logic seems to prefer absolute URLs, so in this case, the url for home should be "/index.html" (not double slash).
76
+ - [x] Site style.css is not present on auto-generated index pages
77
+ - Regeneration issues:
78
+ - Create a power, that power page now exists. But powers.json doesn't have it.
55
79
 
56
80
  # 0.76.0
57
81
  2026-02-11
package/README.md CHANGED
@@ -66,7 +66,7 @@ Start a development server that:
66
66
  - `--port, -p` - Port for development server (default: 8080, serve command only)
67
67
  - `--whitelist, -w` - Path to whitelist file containing patterns for files to include
68
68
  - `--exclude, -e` - Folders to exclude: comma-separated paths relative to source, or path to file with one folder per line
69
- - `--clean` - Clear output directory and ignore cache, forcing full regeneration
69
+ - `--clean` - Delete the `.ursa` cache folder and clear output directory, forcing full regeneration
70
70
 
71
71
  ### Whitelist File Format
72
72
 
package/meta/default.css CHANGED
@@ -152,6 +152,35 @@ nav#nav-global .nav-right-controls {
152
152
  gap: 0;
153
153
  }
154
154
 
155
+ /* Ursa update indicator (loading spinner in nav bar) */
156
+ .ursa-update-indicator {
157
+ display: none;
158
+ align-items: center;
159
+ justify-content: center;
160
+ width: var(--global-nav-height);
161
+ height: var(--global-nav-height);
162
+ opacity: 0.7;
163
+ }
164
+ .ursa-spinner {
165
+ width: 14px;
166
+ height: 14px;
167
+ border: 2px solid rgba(128, 128, 128, 0.3);
168
+ border-top-color: rgba(128, 128, 128, 0.8);
169
+ border-radius: 50%;
170
+ animation: ursa-spin 0.8s linear infinite;
171
+ }
172
+ .ursa-update-gray .ursa-spinner {
173
+ border-color: rgba(128, 128, 128, 0.3);
174
+ border-top-color: rgba(128, 128, 128, 0.8);
175
+ }
176
+ .ursa-update-green .ursa-spinner {
177
+ border-color: rgba(76, 175, 80, 0.3);
178
+ border-top-color: rgba(76, 175, 80, 0.9);
179
+ }
180
+ @keyframes ursa-spin {
181
+ to { transform: rotate(360deg); }
182
+ }
183
+
155
184
  .widget-button {
156
185
  display: flex;
157
186
  align-items: center;
@@ -671,6 +700,8 @@ nav#nav-main-top .top-menu-dropdown {
671
700
  top: 100%;
672
701
  left: 0;
673
702
  min-width: 200px;
703
+ max-height: calc(100vh - var(--global-nav-height) - 20px);
704
+ overflow-y: auto;
674
705
  background-color: var(--widget-bg);
675
706
  border: 1px solid var(--widget-border);
676
707
  border-radius: 4px;
@@ -725,6 +756,8 @@ nav#nav-main-top .top-menu-flyout {
725
756
  left: 100%;
726
757
  top: -1px;
727
758
  min-width: 200px;
759
+ max-height: calc(100vh - var(--global-nav-height) - 20px);
760
+ overflow-y: auto;
728
761
  background-color: var(--widget-bg);
729
762
  border: 1px solid var(--widget-border);
730
763
  border-radius: 4px;