@ryanatkn/gro 0.143.3 → 0.144.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 (51) hide show
  1. package/dist/esbuild_plugin_external_worker.d.ts +2 -2
  2. package/dist/esbuild_plugin_external_worker.d.ts.map +1 -1
  3. package/dist/esbuild_plugin_svelte.d.ts +2 -2
  4. package/dist/esbuild_plugin_svelte.d.ts.map +1 -1
  5. package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +2 -2
  6. package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts.map +1 -1
  7. package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +2 -2
  8. package/dist/esbuild_plugin_sveltekit_shim_app.d.ts.map +1 -1
  9. package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +2 -2
  10. package/dist/esbuild_plugin_sveltekit_shim_env.d.ts.map +1 -1
  11. package/dist/filer.d.ts +3 -3
  12. package/dist/filer.d.ts.map +1 -1
  13. package/dist/filer.js +0 -2
  14. package/dist/gro_plugin_gen.d.ts +2 -2
  15. package/dist/gro_plugin_gen.d.ts.map +1 -1
  16. package/dist/gro_plugin_moss.d.ts +16 -0
  17. package/dist/gro_plugin_moss.d.ts.map +1 -0
  18. package/dist/gro_plugin_moss.js +89 -0
  19. package/dist/gro_plugin_server.d.ts +2 -2
  20. package/dist/gro_plugin_server.d.ts.map +1 -1
  21. package/dist/gro_plugin_sveltekit_app.d.ts +2 -2
  22. package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
  23. package/dist/gro_plugin_sveltekit_library.d.ts +2 -2
  24. package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -1
  25. package/dist/package.d.ts +14 -0
  26. package/dist/package.d.ts.map +1 -1
  27. package/dist/package.js +33 -19
  28. package/dist/package_json.d.ts +6 -4
  29. package/dist/package_json.d.ts.map +1 -1
  30. package/dist/package_json.js +12 -12
  31. package/dist/resolve_node_specifier.d.ts +2 -5
  32. package/dist/resolve_node_specifier.d.ts.map +1 -1
  33. package/dist/resolve_node_specifier.js +233 -44
  34. package/dist/watch_dir.d.ts +2 -2
  35. package/dist/watch_dir.d.ts.map +1 -1
  36. package/package.json +11 -7
  37. package/src/lib/esbuild_plugin_external_worker.ts +2 -2
  38. package/src/lib/esbuild_plugin_svelte.ts +2 -2
  39. package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +2 -2
  40. package/src/lib/esbuild_plugin_sveltekit_shim_app.ts +2 -2
  41. package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +2 -2
  42. package/src/lib/filer.ts +3 -6
  43. package/src/lib/gro_plugin_gen.ts +2 -2
  44. package/src/lib/gro_plugin_moss.ts +122 -0
  45. package/src/lib/gro_plugin_server.ts +2 -2
  46. package/src/lib/gro_plugin_sveltekit_app.ts +2 -2
  47. package/src/lib/gro_plugin_sveltekit_library.ts +2 -2
  48. package/src/lib/package.ts +33 -19
  49. package/src/lib/package_json.ts +15 -14
  50. package/src/lib/resolve_node_specifier.ts +267 -49
  51. package/src/lib/watch_dir.ts +2 -2
@@ -0,0 +1,122 @@
1
+ import {EMPTY_OBJECT} from '@ryanatkn/belt/object.js';
2
+ import {throttle} from '@ryanatkn/belt/throttle.js';
3
+ import {Unreachable_Error} from '@ryanatkn/belt/error.js';
4
+ import {writeFileSync} from 'node:fs';
5
+ import {collect_css_classes, Css_Classes} from '@ryanatkn/moss/css_class_helpers.js';
6
+ import {css_classes_by_name} from '@ryanatkn/moss/css_classes.js';
7
+
8
+ import type {Plugin} from './plugin.js';
9
+ import type {Args} from './args.js';
10
+ import type {Cleanup_Watch} from './filer.js';
11
+ import {format_file} from './format_file.js';
12
+ import type {File_Filter} from './path.js';
13
+
14
+ export const generate_classes_css = (classes: Iterable<string>): string => {
15
+ let css = '';
16
+ for (const c of classes) {
17
+ const v = css_classes_by_name[c];
18
+ if (!v) {
19
+ // diagnostic
20
+ // if (!/^[a-z_0-9]+$/.test(c)) {
21
+ // console.error('invalid class detected, fix the regexps', c);
22
+ // }
23
+ continue;
24
+ }
25
+ if ('declaration' in v) {
26
+ css += `.${c} { ${v.declaration} }\n`;
27
+ } else {
28
+ css += v.ruleset + '\n';
29
+ }
30
+ }
31
+
32
+ return css;
33
+ };
34
+
35
+ const FLUSH_DEBOUNCE_DELAY = 500;
36
+
37
+ export interface Task_Args extends Args {
38
+ watch?: boolean;
39
+ }
40
+
41
+ export interface Options {
42
+ include_classes?: string[] | Set<string> | null;
43
+ outfile?: string;
44
+ filter_file?: File_Filter | null;
45
+ flush_debounce_delay?: number;
46
+ banner?: string;
47
+ }
48
+
49
+ export const gro_plugin_moss = ({
50
+ include_classes = null,
51
+ outfile = 'src/routes/moss.css', // TODO maybe support multiple files using file filters to check where to collect them?
52
+ filter_file = (p) => !p.includes('.test.') && !p.includes('/test/'),
53
+ flush_debounce_delay = FLUSH_DEBOUNCE_DELAY,
54
+ banner = 'generated by gro_plugin_moss',
55
+ }: Options = EMPTY_OBJECT): Plugin => {
56
+ const css_classes = new Css_Classes(
57
+ Array.isArray(include_classes) ? new Set(include_classes) : include_classes,
58
+ );
59
+
60
+ let previous_output: string | undefined;
61
+
62
+ let flushing_timeout: NodeJS.Timeout | undefined;
63
+ const queue_gen = () => {
64
+ if (flushing_timeout === undefined) {
65
+ flushing_timeout = setTimeout(() => {
66
+ flushing_timeout = undefined;
67
+ void flush_gen_queue();
68
+ }); // the timeout batches synchronously
69
+ }
70
+ };
71
+ const flush_gen_queue = throttle(
72
+ async () => {
73
+ const css = generate_classes_css(css_classes.get_sorted_array());
74
+ const contents = `/* ${banner} */\n\n${css}\n\n/* ${banner} */`;
75
+ const output = await format_file(contents, {filepath: outfile});
76
+ // TODO think about using gen to implement this, would have some nice benefits like automatic change detection
77
+ if (output === previous_output) return;
78
+ previous_output = output;
79
+ writeFileSync(outfile, output);
80
+ },
81
+ {delay: flush_debounce_delay, when: 'trailing'},
82
+ );
83
+
84
+ let cleanup: Cleanup_Watch | undefined;
85
+
86
+ return {
87
+ name: 'gro_plugin_moss',
88
+ setup: async ({filer}) => {
89
+ // When a file builds, check it and its tree of dependents
90
+ // for any `.gen.` files that need to run.
91
+ cleanup = await filer.watch((change, source_file) => {
92
+ if (filter_file && !filter_file(source_file.id)) {
93
+ return;
94
+ }
95
+ switch (change.type) {
96
+ case 'add':
97
+ case 'update': {
98
+ if (source_file.contents !== null) {
99
+ const classes = collect_css_classes(source_file.contents);
100
+ css_classes.add(source_file.id, classes);
101
+ queue_gen();
102
+ }
103
+ break;
104
+ }
105
+ case 'delete': {
106
+ css_classes.delete(source_file.id);
107
+ break;
108
+ }
109
+ default:
110
+ throw new Unreachable_Error(change.type);
111
+ }
112
+ });
113
+ queue_gen();
114
+ },
115
+ teardown: async () => {
116
+ if (cleanup !== undefined) {
117
+ await cleanup();
118
+ cleanup = undefined;
119
+ }
120
+ },
121
+ };
122
+ };
@@ -33,7 +33,7 @@ export const has_server = (path = SERVER_SOURCE_ID): Result<object, {message: st
33
33
  return {ok: true};
34
34
  };
35
35
 
36
- export interface Options {
36
+ export interface Gro_Plugin_Server_Options {
37
37
  /**
38
38
  * same as esbuild's `entryPoints`
39
39
  */
@@ -121,7 +121,7 @@ export const gro_plugin_server = ({
121
121
  rebuild_throttle_delay = 1000,
122
122
  cli_command,
123
123
  run, // `dev` default is not available in this scope
124
- }: Options = {}): Plugin => {
124
+ }: Gro_Plugin_Server_Options = {}): Plugin => {
125
125
  let build_ctx: esbuild.BuildContext | null = null;
126
126
  let watcher: Watch_Node_Fs | null = null;
127
127
  let server_process: Restartable_Process | null = null;
@@ -13,7 +13,7 @@ import {default_sveltekit_config} from './sveltekit_config.js';
13
13
  import {SOURCE_DIRNAME} from './constants.js';
14
14
  import {VITE_CLI} from './sveltekit_helpers.js';
15
15
 
16
- export interface Options {
16
+ export interface Gro_Plugin_Sveltekit_App_Options {
17
17
  /**
18
18
  * Used for finalizing a SvelteKit build like adding a `.nojekyll` file for GitHub Pages.
19
19
  * @default 'github_pages'
@@ -53,7 +53,7 @@ export const gro_plugin_sveltekit_app = ({
53
53
  well_known_src_json,
54
54
  well_known_src_files,
55
55
  vite_cli = VITE_CLI,
56
- }: Options = {}): Plugin => {
56
+ }: Gro_Plugin_Sveltekit_App_Options = {}): Plugin => {
57
57
  let sveltekit_process: Spawned_Process | undefined = undefined;
58
58
  return {
59
59
  name: 'gro_plugin_sveltekit_app',
@@ -9,7 +9,7 @@ import {
9
9
  type Svelte_Package_Options,
10
10
  } from './sveltekit_helpers.js';
11
11
 
12
- export interface Options {
12
+ export interface Gro_Plugin_Sveltekit_Library_Options {
13
13
  /**
14
14
  * The options passed to the SvelteKit packaging CLI.
15
15
  * @see https://kit.svelte.dev/docs/packaging#options
@@ -25,7 +25,7 @@ export interface Options {
25
25
  export const gro_plugin_sveltekit_library = ({
26
26
  svelte_package_options,
27
27
  svelte_package_cli = SVELTE_PACKAGE_CLI,
28
- }: Options = {}): Plugin => {
28
+ }: Gro_Plugin_Sveltekit_Library_Options = {}): Plugin => {
29
29
  return {
30
30
  name: 'gro_plugin_sveltekit_library',
31
31
  setup: async ({dev, log, config}) => {
@@ -5,7 +5,7 @@ import type {Src_Json} from './src_json.js';
5
5
 
6
6
  export const package_json = {
7
7
  name: '@ryanatkn/gro',
8
- version: '0.143.3',
8
+ version: '0.144.0',
9
9
  description: 'task runner and toolkit extending SvelteKit',
10
10
  motto: 'generate, run, optimize',
11
11
  glyph: '🌰',
@@ -44,11 +44,11 @@ export const package_json = {
44
44
  'typescript',
45
45
  ],
46
46
  dependencies: {
47
- '@ryanatkn/belt': '^0.25.3',
47
+ '@ryanatkn/belt': '^0.26.0',
48
48
  chokidar: '^4.0.1',
49
49
  dotenv: '^16.4.5',
50
50
  'es-module-lexer': '^1.5.4',
51
- 'esm-env': '^1.0.0',
51
+ 'esm-env': '^1.1.4',
52
52
  mri: '^1.2.0',
53
53
  prettier: '^3.3.3',
54
54
  'prettier-plugin-svelte': '^3.2.7',
@@ -61,21 +61,21 @@ export const package_json = {
61
61
  '@changesets/changelog-git': '^0.2.0',
62
62
  '@changesets/types': '^6.0.0',
63
63
  '@ryanatkn/eslint-config': '^0.5.5',
64
- '@ryanatkn/fuz': '^0.130.1',
64
+ '@ryanatkn/fuz': '^0.130.3',
65
65
  '@ryanatkn/moss': '^0.18.2',
66
66
  '@sveltejs/adapter-static': '^3.0.6',
67
67
  '@sveltejs/kit': '^2.7.3',
68
68
  '@sveltejs/package': '^2.3.7',
69
69
  '@sveltejs/vite-plugin-svelte': '^4.0.0',
70
70
  '@types/fs-extra': '^11.0.4',
71
- '@types/node': '^22.8.1',
71
+ '@types/node': '^22.8.4',
72
72
  esbuild: '^0.21.5',
73
73
  eslint: '^9.13.0',
74
74
  'eslint-plugin-svelte': '^2.46.0',
75
- svelte: '^5.1.3',
75
+ svelte: '^5.1.5',
76
76
  'svelte-check': '^4.0.5',
77
77
  typescript: '^5.6.3',
78
- 'typescript-eslint': '^8.11.0',
78
+ 'typescript-eslint': '^8.12.1',
79
79
  uvu: '^0.5.6',
80
80
  },
81
81
  prettier: {
@@ -157,6 +157,10 @@ export const package_json = {
157
157
  types: './dist/gro_plugin_gen.d.ts',
158
158
  default: './dist/gro_plugin_gen.js',
159
159
  },
160
+ './gro_plugin_moss.js': {
161
+ types: './dist/gro_plugin_moss.d.ts',
162
+ default: './dist/gro_plugin_moss.js',
163
+ },
160
164
  './gro_plugin_server.js': {
161
165
  types: './dist/gro_plugin_server.d.ts',
162
166
  default: './dist/gro_plugin_server.js',
@@ -267,7 +271,7 @@ export const package_json = {
267
271
 
268
272
  export const src_json = {
269
273
  name: '@ryanatkn/gro',
270
- version: '0.143.3',
274
+ version: '0.144.0',
271
275
  modules: {
272
276
  '.': {
273
277
  path: 'index.ts',
@@ -431,14 +435,14 @@ export const src_json = {
431
435
  './esbuild_plugin_external_worker.js': {
432
436
  path: 'esbuild_plugin_external_worker.ts',
433
437
  declarations: [
434
- {name: 'Options', kind: 'type'},
438
+ {name: 'Esbuild_Plugin_External_Worker_Options', kind: 'type'},
435
439
  {name: 'esbuild_plugin_external_worker', kind: 'function'},
436
440
  ],
437
441
  },
438
442
  './esbuild_plugin_svelte.js': {
439
443
  path: 'esbuild_plugin_svelte.ts',
440
444
  declarations: [
441
- {name: 'Options', kind: 'type'},
445
+ {name: 'Esbuild_Plugin_Svelte_Options', kind: 'type'},
442
446
  {name: 'esbuild_plugin_svelte', kind: 'function'},
443
447
  ],
444
448
  },
@@ -449,21 +453,21 @@ export const src_json = {
449
453
  './esbuild_plugin_sveltekit_shim_alias.js': {
450
454
  path: 'esbuild_plugin_sveltekit_shim_alias.ts',
451
455
  declarations: [
452
- {name: 'Options', kind: 'type'},
456
+ {name: 'Esbuild_Plugin_Sveltekit_Shim_Alias_Options', kind: 'type'},
453
457
  {name: 'esbuild_plugin_sveltekit_shim_alias', kind: 'function'},
454
458
  ],
455
459
  },
456
460
  './esbuild_plugin_sveltekit_shim_app.js': {
457
461
  path: 'esbuild_plugin_sveltekit_shim_app.ts',
458
462
  declarations: [
459
- {name: 'Options', kind: 'type'},
463
+ {name: 'Esbuild_Plugin_Sveltekit_Shim_App_Options', kind: 'type'},
460
464
  {name: 'esbuild_plugin_sveltekit_shim_app', kind: 'function'},
461
465
  ],
462
466
  },
463
467
  './esbuild_plugin_sveltekit_shim_env.js': {
464
468
  path: 'esbuild_plugin_sveltekit_shim_env.ts',
465
469
  declarations: [
466
- {name: 'Options', kind: 'type'},
470
+ {name: 'Esbuild_Plugin_Sveltekit_Shim_Env_Options', kind: 'type'},
467
471
  {name: 'esbuild_plugin_sveltekit_shim_env', kind: 'function'},
468
472
  ],
469
473
  },
@@ -473,7 +477,7 @@ export const src_json = {
473
477
  {name: 'Source_File', kind: 'type'},
474
478
  {name: 'Cleanup_Watch', kind: 'type'},
475
479
  {name: 'On_Filer_Change', kind: 'type'},
476
- {name: 'Options', kind: 'type'},
480
+ {name: 'Filer_Options', kind: 'type'},
477
481
  {name: 'Filer', kind: 'class'},
478
482
  ],
479
483
  },
@@ -594,17 +598,26 @@ export const src_json = {
594
598
  path: 'gro_plugin_gen.ts',
595
599
  declarations: [
596
600
  {name: 'Task_Args', kind: 'type'},
597
- {name: 'Options', kind: 'type'},
601
+ {name: 'Gro_Plugin_Gen_Options', kind: 'type'},
598
602
  {name: 'gro_plugin_gen', kind: 'function'},
599
603
  {name: 'filter_dependents', kind: 'function'},
600
604
  ],
601
605
  },
606
+ './gro_plugin_moss.js': {
607
+ path: 'gro_plugin_moss.ts',
608
+ declarations: [
609
+ {name: 'generate_classes_css', kind: 'function'},
610
+ {name: 'Task_Args', kind: 'type'},
611
+ {name: 'Options', kind: 'type'},
612
+ {name: 'gro_plugin_moss', kind: 'function'},
613
+ ],
614
+ },
602
615
  './gro_plugin_server.js': {
603
616
  path: 'gro_plugin_server.ts',
604
617
  declarations: [
605
618
  {name: 'SERVER_SOURCE_ID', kind: 'variable'},
606
619
  {name: 'has_server', kind: 'function'},
607
- {name: 'Options', kind: 'type'},
620
+ {name: 'Gro_Plugin_Server_Options', kind: 'type'},
608
621
  {name: 'Outpaths', kind: 'type'},
609
622
  {name: 'Create_Outpaths', kind: 'type'},
610
623
  {name: 'gro_plugin_server', kind: 'function'},
@@ -613,7 +626,7 @@ export const src_json = {
613
626
  './gro_plugin_sveltekit_app.js': {
614
627
  path: 'gro_plugin_sveltekit_app.ts',
615
628
  declarations: [
616
- {name: 'Options', kind: 'type'},
629
+ {name: 'Gro_Plugin_Sveltekit_App_Options', kind: 'type'},
617
630
  {name: 'Host_Target', kind: 'type'},
618
631
  {name: 'Copy_File_Filter', kind: 'type'},
619
632
  {name: 'gro_plugin_sveltekit_app', kind: 'function'},
@@ -622,7 +635,7 @@ export const src_json = {
622
635
  './gro_plugin_sveltekit_library.js': {
623
636
  path: 'gro_plugin_sveltekit_library.ts',
624
637
  declarations: [
625
- {name: 'Options', kind: 'type'},
638
+ {name: 'Gro_Plugin_Sveltekit_Library_Options', kind: 'type'},
626
639
  {name: 'gro_plugin_sveltekit_library', kind: 'function'},
627
640
  ],
628
641
  },
@@ -704,6 +717,7 @@ export const src_json = {
704
717
  {name: 'Package_Json_Repository', kind: 'variable'},
705
718
  {name: 'Package_Json_Author', kind: 'variable'},
706
719
  {name: 'Package_Json_Funding', kind: 'variable'},
720
+ {name: 'Export_Value', kind: 'variable'},
707
721
  {name: 'Package_Json_Exports', kind: 'variable'},
708
722
  {name: 'Package_Json', kind: 'variable'},
709
723
  {name: 'Map_Package_Json', kind: 'type'},
@@ -1037,7 +1051,7 @@ export const src_json = {
1037
1051
  {name: 'Watcher_Change', kind: 'type'},
1038
1052
  {name: 'Watcher_Change_Type', kind: 'type'},
1039
1053
  {name: 'Watcher_Change_Callback', kind: 'type'},
1040
- {name: 'Options', kind: 'type'},
1054
+ {name: 'Watch_Dir_Options', kind: 'type'},
1041
1055
  {name: 'watch_dir', kind: 'function'},
1042
1056
  ],
1043
1057
  },
@@ -63,20 +63,21 @@ export const Package_Json_Funding = z.union([
63
63
  ]);
64
64
  export type Package_Json_Funding = z.infer<typeof Package_Json_Funding>;
65
65
 
66
- // exports: {
67
- // './': './index.js',
68
- // './record': {default: './record.js'},
69
- // './export_condition': {default: {development: './ec1', default: './ec2.js'}},
70
- // }
71
- export const Package_Json_Exports = z.record(
72
- z
73
- .union([
74
- z.string(),
75
- z.record(z.string().optional()),
76
- z.record(z.record(z.string().optional()).optional()),
77
- ])
78
- .optional(),
79
- );
66
+ // Helper to create a recursive type that represents export conditions and values
67
+ const create_export_value_schema = (): z.ZodType => {
68
+ return z.lazy(() => z.union([z.string(), z.null(), z.record(z.lazy(() => export_value_schema))]));
69
+ };
70
+
71
+ // The base export value schema that can be a string, null, or nested conditions
72
+ const export_value_schema = create_export_value_schema();
73
+ export const Export_Value = export_value_schema;
74
+ export type Export_Value = z.infer<typeof Export_Value>;
75
+
76
+ // Package exports can be:
77
+ // 1. A string (shorthand for main export)
78
+ // 2. null (to block exports)
79
+ // 3. A record of export conditions/paths
80
+ export const Package_Json_Exports = z.union([z.string(), z.null(), z.record(export_value_schema)]);
80
81
  export type Package_Json_Exports = z.infer<typeof Package_Json_Exports>;
81
82
 
82
83
  /**