@ryanatkn/gro 0.143.3 → 0.144.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.
Files changed (61) 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.config.default.js +5 -5
  15. package/dist/gro_plugin_gen.d.ts +2 -2
  16. package/dist/gro_plugin_gen.d.ts.map +1 -1
  17. package/dist/gro_plugin_moss.d.ts +22 -0
  18. package/dist/gro_plugin_moss.d.ts.map +1 -0
  19. package/dist/gro_plugin_moss.js +100 -0
  20. package/dist/gro_plugin_server.d.ts +2 -2
  21. package/dist/gro_plugin_server.d.ts.map +1 -1
  22. package/dist/gro_plugin_sveltekit_app.d.ts +2 -2
  23. package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
  24. package/dist/gro_plugin_sveltekit_library.d.ts +2 -2
  25. package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -1
  26. package/dist/moss_helpers.d.ts +1 -1
  27. package/dist/moss_helpers.d.ts.map +1 -1
  28. package/dist/moss_helpers.js +3 -3
  29. package/dist/package.d.ts +17 -0
  30. package/dist/package.d.ts.map +1 -1
  31. package/dist/package.js +36 -20
  32. package/dist/package_json.d.ts +6 -4
  33. package/dist/package_json.d.ts.map +1 -1
  34. package/dist/package_json.js +12 -12
  35. package/dist/resolve_node_specifier.d.ts +2 -5
  36. package/dist/resolve_node_specifier.d.ts.map +1 -1
  37. package/dist/resolve_node_specifier.js +233 -44
  38. package/dist/sveltekit_helpers.d.ts +1 -1
  39. package/dist/sveltekit_helpers.d.ts.map +1 -1
  40. package/dist/sveltekit_helpers.js +2 -2
  41. package/dist/watch_dir.d.ts +2 -2
  42. package/dist/watch_dir.d.ts.map +1 -1
  43. package/package.json +12 -8
  44. package/src/lib/esbuild_plugin_external_worker.ts +2 -2
  45. package/src/lib/esbuild_plugin_svelte.ts +2 -2
  46. package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +2 -2
  47. package/src/lib/esbuild_plugin_sveltekit_shim_app.ts +2 -2
  48. package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +2 -2
  49. package/src/lib/filer.ts +3 -6
  50. package/src/lib/gro.config.default.ts +5 -5
  51. package/src/lib/gro_plugin_gen.ts +2 -2
  52. package/src/lib/gro_plugin_moss.ts +140 -0
  53. package/src/lib/gro_plugin_server.ts +2 -2
  54. package/src/lib/gro_plugin_sveltekit_app.ts +2 -2
  55. package/src/lib/gro_plugin_sveltekit_library.ts +2 -2
  56. package/src/lib/moss_helpers.ts +2 -3
  57. package/src/lib/package.ts +36 -20
  58. package/src/lib/package_json.ts +15 -14
  59. package/src/lib/resolve_node_specifier.ts +267 -49
  60. package/src/lib/sveltekit_helpers.ts +1 -2
  61. package/src/lib/watch_dir.ts +2 -2
@@ -19,7 +19,7 @@ export const has_sveltekit_app = () => {
19
19
  // TODO check for routes?
20
20
  return { ok: true };
21
21
  };
22
- export const has_sveltekit_library = (package_json, sveltekit_config = default_sveltekit_config, dep_name = SVELTE_PACKAGE_DEP_NAME, pm_cli = PM_CLI_DEFAULT) => {
22
+ export const has_sveltekit_library = (package_json, sveltekit_config = default_sveltekit_config, dep_name = SVELTE_PACKAGE_DEP_NAME) => {
23
23
  const has_sveltekit_app_result = has_sveltekit_app();
24
24
  if (!has_sveltekit_app_result.ok) {
25
25
  return has_sveltekit_app_result;
@@ -30,7 +30,7 @@ export const has_sveltekit_library = (package_json, sveltekit_config = default_s
30
30
  if (!has_dep(dep_name, package_json)) {
31
31
  return {
32
32
  ok: false,
33
- message: `no dependency found in package.json for ${dep_name}, install it with \`${pm_cli} install -D ${dep_name}\``,
33
+ message: `no dependency found in package.json for ${dep_name}`,
34
34
  };
35
35
  }
36
36
  return { ok: true };
@@ -11,7 +11,7 @@ export interface Watcher_Change {
11
11
  }
12
12
  export type Watcher_Change_Type = 'add' | 'update' | 'delete';
13
13
  export type Watcher_Change_Callback = (change: Watcher_Change) => void;
14
- export interface Options {
14
+ export interface Watch_Dir_Options {
15
15
  dir: string;
16
16
  on_change: Watcher_Change_Callback;
17
17
  filter?: Path_Filter | null | undefined;
@@ -25,5 +25,5 @@ export interface Options {
25
25
  /**
26
26
  * Watch for changes on the filesystem using chokidar.
27
27
  */
28
- export declare const watch_dir: ({ dir, on_change, filter, absolute, chokidar, }: Options) => Watch_Node_Fs;
28
+ export declare const watch_dir: ({ dir, on_change, filter, absolute, chokidar, }: Watch_Dir_Options) => Watch_Node_Fs;
29
29
  //# sourceMappingURL=watch_dir.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"watch_dir.d.ts","sourceRoot":"../src/lib/","sources":["watch_dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,eAAe,EAAiB,MAAM,UAAU,CAAC;AAKrE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAI3C,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,OAAO;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,oDAMnB,OAAO,KAAG,aA6CZ,CAAC"}
1
+ {"version":3,"file":"watch_dir.d.ts","sourceRoot":"../src/lib/","sources":["watch_dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,eAAe,EAAiB,MAAM,UAAU,CAAC;AAKrE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAI3C,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9D,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,oDAMnB,iBAAiB,KAAG,aA6CtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryanatkn/gro",
3
- "version": "0.143.3",
3
+ "version": "0.144.1",
4
4
  "description": "task runner and toolkit extending SvelteKit",
5
5
  "motto": "generate, run, optimize",
6
6
  "glyph": "🌰",
@@ -49,11 +49,11 @@
49
49
  "typescript"
50
50
  ],
51
51
  "dependencies": {
52
- "@ryanatkn/belt": "^0.25.3",
52
+ "@ryanatkn/belt": "^0.26.0",
53
53
  "chokidar": "^4.0.1",
54
54
  "dotenv": "^16.4.5",
55
55
  "es-module-lexer": "^1.5.4",
56
- "esm-env": "^1.0.0",
56
+ "esm-env": "^1.1.4",
57
57
  "mri": "^1.2.0",
58
58
  "prettier": "^3.3.3",
59
59
  "prettier-plugin-svelte": "^3.2.7",
@@ -69,21 +69,21 @@
69
69
  "@changesets/changelog-git": "^0.2.0",
70
70
  "@changesets/types": "^6.0.0",
71
71
  "@ryanatkn/eslint-config": "^0.5.5",
72
- "@ryanatkn/fuz": "^0.130.1",
73
- "@ryanatkn/moss": "^0.18.2",
72
+ "@ryanatkn/fuz": "^0.130.3",
73
+ "@ryanatkn/moss": "^0.19.0",
74
74
  "@sveltejs/adapter-static": "^3.0.6",
75
75
  "@sveltejs/kit": "^2.7.3",
76
76
  "@sveltejs/package": "^2.3.7",
77
77
  "@sveltejs/vite-plugin-svelte": "^4.0.0",
78
78
  "@types/fs-extra": "^11.0.4",
79
- "@types/node": "^22.8.1",
79
+ "@types/node": "^22.8.4",
80
80
  "esbuild": "^0.21.5",
81
81
  "eslint": "^9.13.0",
82
82
  "eslint-plugin-svelte": "^2.46.0",
83
- "svelte": "^5.1.3",
83
+ "svelte": "^5.1.5",
84
84
  "svelte-check": "^4.0.5",
85
85
  "typescript": "^5.6.3",
86
- "typescript-eslint": "^8.11.0",
86
+ "typescript-eslint": "^8.12.1",
87
87
  "uvu": "^0.5.6"
88
88
  },
89
89
  "prettier": {
@@ -250,6 +250,10 @@
250
250
  "types": "./dist/gro_plugin_gen.d.ts",
251
251
  "default": "./dist/gro_plugin_gen.js"
252
252
  },
253
+ "./gro_plugin_moss.js": {
254
+ "types": "./dist/gro_plugin_moss.d.ts",
255
+ "default": "./dist/gro_plugin_moss.js"
256
+ },
253
257
  "./gro_plugin_server.js": {
254
258
  "types": "./dist/gro_plugin_server.d.ts",
255
259
  "default": "./dist/gro_plugin_server.js"
@@ -13,7 +13,7 @@ import {esbuild_plugin_svelte} from './esbuild_plugin_svelte.js';
13
13
  import type {Parsed_Sveltekit_Config} from './sveltekit_config.js';
14
14
  import type {Path_Id} from './path.js';
15
15
 
16
- export interface Options {
16
+ export interface Esbuild_Plugin_External_Worker_Options {
17
17
  dev: boolean;
18
18
  build_options: esbuild.BuildOptions;
19
19
  dir?: string;
@@ -47,7 +47,7 @@ export const esbuild_plugin_external_worker = ({
47
47
  env_files,
48
48
  ambient_env,
49
49
  log,
50
- }: Options): esbuild.Plugin => ({
50
+ }: Esbuild_Plugin_External_Worker_Options): esbuild.Plugin => ({
51
51
  name: 'external_worker',
52
52
  setup: (build) => {
53
53
  const builds: Map<string, Promise<esbuild.BuildResult>> = new Map();
@@ -19,7 +19,7 @@ import {
19
19
  } from './sveltekit_config.js';
20
20
  import {TS_MATCHER} from './constants.js';
21
21
 
22
- export interface Options {
22
+ export interface Esbuild_Plugin_Svelte_Options {
23
23
  dev: boolean;
24
24
  base_url: Parsed_Sveltekit_Config['base_url'];
25
25
  dir?: string;
@@ -30,7 +30,7 @@ export interface Options {
30
30
  is_ts?: (filename: string) => boolean;
31
31
  }
32
32
 
33
- export const esbuild_plugin_svelte = (options: Options): esbuild.Plugin => {
33
+ export const esbuild_plugin_svelte = (options: Esbuild_Plugin_Svelte_Options): esbuild.Plugin => {
34
34
  const {
35
35
  dev,
36
36
  base_url,
@@ -2,7 +2,7 @@ import type * as esbuild from 'esbuild';
2
2
  import {escape_regexp} from '@ryanatkn/belt/regexp.js';
3
3
  import {join} from 'node:path';
4
4
 
5
- export interface Options {
5
+ export interface Esbuild_Plugin_Sveltekit_Shim_Alias_Options {
6
6
  dir?: string;
7
7
  alias?: Record<string, string>;
8
8
  }
@@ -10,7 +10,7 @@ export interface Options {
10
10
  export const esbuild_plugin_sveltekit_shim_alias = ({
11
11
  dir = process.cwd(),
12
12
  alias,
13
- }: Options): esbuild.Plugin => ({
13
+ }: Esbuild_Plugin_Sveltekit_Shim_Alias_Options): esbuild.Plugin => ({
14
14
  name: 'sveltekit_shim_alias',
15
15
  setup: (build) => {
16
16
  const aliases: Record<string, string> = {$lib: 'src/lib', ...alias};
@@ -8,7 +8,7 @@ import {
8
8
  import type {Parsed_Sveltekit_Config} from './sveltekit_config.js';
9
9
  import {EVERYTHING_MATCHER} from './constants.js';
10
10
 
11
- export interface Options {
11
+ export interface Esbuild_Plugin_Sveltekit_Shim_App_Options {
12
12
  dev: boolean;
13
13
  base_url: Parsed_Sveltekit_Config['base_url'];
14
14
  assets_url: Parsed_Sveltekit_Config['assets_url'];
@@ -18,7 +18,7 @@ export const esbuild_plugin_sveltekit_shim_app = ({
18
18
  dev,
19
19
  base_url,
20
20
  assets_url,
21
- }: Options): esbuild.Plugin => ({
21
+ }: Esbuild_Plugin_Sveltekit_Shim_App_Options): esbuild.Plugin => ({
22
22
  name: 'sveltekit_shim_app',
23
23
  setup: (build) => {
24
24
  build.onResolve({filter: /^\$app\/(forms|navigation|stores)$/}, ({path, ...rest}) =>
@@ -4,7 +4,7 @@ import {render_env_shim_module} from './sveltekit_shim_env.js';
4
4
  import {EVERYTHING_MATCHER} from './constants.js';
5
5
  import {SVELTEKIT_ENV_MATCHER} from './sveltekit_helpers.js';
6
6
 
7
- export interface Options {
7
+ export interface Esbuild_Plugin_Sveltekit_Shim_Env_Options {
8
8
  dev: boolean;
9
9
  public_prefix?: string;
10
10
  private_prefix?: string;
@@ -22,7 +22,7 @@ export const esbuild_plugin_sveltekit_shim_env = ({
22
22
  env_dir,
23
23
  env_files,
24
24
  ambient_env,
25
- }: Options): esbuild.Plugin => ({
25
+ }: Esbuild_Plugin_Sveltekit_Shim_Env_Options): esbuild.Plugin => ({
26
26
  name: 'sveltekit_shim_env',
27
27
  setup: (build) => {
28
28
  build.onResolve({filter: SVELTEKIT_ENV_MATCHER}, ({path}) => ({path, namespace}));
package/src/lib/filer.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  watch_dir,
10
10
  type Watch_Node_Fs,
11
11
  type Watcher_Change,
12
- type Options as Watch_Dir_Options,
12
+ type Watch_Dir_Options,
13
13
  type Watcher_Change_Callback,
14
14
  } from './watch_dir.js';
15
15
  import {paths} from './paths.js';
@@ -20,14 +20,11 @@ import {map_sveltekit_aliases} from './sveltekit_helpers.js';
20
20
  import {Unreachable_Error} from '@ryanatkn/belt/error.js';
21
21
  import {resolve_node_specifier} from './resolve_node_specifier.js';
22
22
  import type {Package_Json} from './package_json.js';
23
- // TODO see below
24
- // import {resolve_node_specifier} from './resolve_node_specifier.js';
25
23
 
26
24
  const aliases = Object.entries(default_sveltekit_config.alias);
27
25
 
28
26
  export interface Source_File {
29
27
  id: Path_Id;
30
- // TODO add // mtime: number;
31
28
  /**
32
29
  * `null` contents means it doesn't exist.
33
30
  * We create the file in memory to track its dependents regardless of its existence on disk.
@@ -47,7 +44,7 @@ export type Cleanup_Watch = () => Promise<void>;
47
44
 
48
45
  export type On_Filer_Change = (change: Watcher_Change, source_file: Source_File) => void;
49
46
 
50
- export interface Options {
47
+ export interface Filer_Options {
51
48
  watch_dir?: typeof watch_dir;
52
49
  watch_dir_options?: Partial<Omit_Strict<Watch_Dir_Options, 'on_change'>>;
53
50
  package_json_cache?: Record<string, Package_Json>;
@@ -63,7 +60,7 @@ export class Filer {
63
60
 
64
61
  #package_json_cache: Record<string, Package_Json>;
65
62
 
66
- constructor(options: Options = EMPTY_OBJECT) {
63
+ constructor(options: Filer_Options = EMPTY_OBJECT) {
67
64
  this.#watch_dir = options.watch_dir ?? watch_dir;
68
65
  this.#watch_dir_options = options.watch_dir_options ?? EMPTY_OBJECT;
69
66
  this.root_dir = resolve(options.watch_dir_options?.dir ?? paths.source);
@@ -4,7 +4,7 @@ import {has_server, gro_plugin_server} from './gro_plugin_server.js';
4
4
  import {gro_plugin_sveltekit_app} from './gro_plugin_sveltekit_app.js';
5
5
  import {has_sveltekit_app, has_sveltekit_library} from './sveltekit_helpers.js';
6
6
  import {gro_plugin_gen} from './gro_plugin_gen.js';
7
- import {load_moss_plugin} from './moss_helpers.js';
7
+ import {gro_plugin_moss, has_moss_dep} from './gro_plugin_moss.js';
8
8
 
9
9
  /**
10
10
  * This is the default config that's passed to `gro.config.ts`
@@ -18,20 +18,20 @@ import {load_moss_plugin} from './moss_helpers.js';
18
18
  const config: Create_Gro_Config = async (cfg) => {
19
19
  const [
20
20
  moss_plugin_result,
21
- has_sveltekit_library_result,
22
21
  has_server_result,
22
+ has_sveltekit_library_result,
23
23
  has_sveltekit_app_result,
24
24
  ] = await Promise.all([
25
- load_moss_plugin(),
26
- has_sveltekit_library(),
25
+ has_moss_dep(),
27
26
  has_server(),
27
+ has_sveltekit_library(),
28
28
  has_sveltekit_app(),
29
29
  ]);
30
30
 
31
31
  cfg.plugins = () =>
32
32
  [
33
33
  // put things that generate files before SvelteKit so it can see them
34
- moss_plugin_result.ok ? moss_plugin_result.gro_plugin_moss() : null,
34
+ moss_plugin_result.ok ? gro_plugin_moss() : null,
35
35
  gro_plugin_gen(),
36
36
  has_server_result.ok ? gro_plugin_server() : null,
37
37
  has_sveltekit_library_result.ok ? gro_plugin_sveltekit_library() : null,
@@ -16,7 +16,7 @@ export interface Task_Args extends Args {
16
16
  watch?: boolean;
17
17
  }
18
18
 
19
- export interface Options {
19
+ export interface Gro_Plugin_Gen_Options {
20
20
  input_paths?: string[];
21
21
  root_dirs?: string[];
22
22
  flush_debounce_delay?: number;
@@ -26,7 +26,7 @@ export const gro_plugin_gen = ({
26
26
  input_paths = [paths.source],
27
27
  root_dirs = [paths.source],
28
28
  flush_debounce_delay = FLUSH_DEBOUNCE_DELAY,
29
- }: Options = EMPTY_OBJECT): Plugin => {
29
+ }: Gro_Plugin_Gen_Options = EMPTY_OBJECT): Plugin => {
30
30
  let flushing_timeout: NodeJS.Timeout | undefined;
31
31
  const queued_files: Set<string> = new Set();
32
32
  const queue_gen = (gen_file_id: string) => {
@@ -0,0 +1,140 @@
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
+ import type {Result} from '@ryanatkn/belt/result.js';
8
+
9
+ import type {Plugin} from './plugin.js';
10
+ import type {Args} from './args.js';
11
+ import type {Cleanup_Watch} from './filer.js';
12
+ import {format_file} from './format_file.js';
13
+ import type {File_Filter} from './path.js';
14
+ import {has_dep, type Package_Json} from './package_json.js';
15
+
16
+ export const MOSS_PACKAGE_DEP_NAME = '@ryanatkn/moss';
17
+
18
+ export const has_moss_dep = (
19
+ package_json?: Package_Json,
20
+ dep_name = MOSS_PACKAGE_DEP_NAME,
21
+ ): Result<object, {message: string}> => {
22
+ if (!has_dep(dep_name, package_json)) {
23
+ return {
24
+ ok: false,
25
+ message: `no dependency found in package.json for ${dep_name}`,
26
+ };
27
+ }
28
+
29
+ return {ok: true};
30
+ };
31
+
32
+ export const generate_classes_css = (classes: Iterable<string>): string => {
33
+ let css = '';
34
+ for (const c of classes) {
35
+ const v = css_classes_by_name[c];
36
+ if (!v) {
37
+ // diagnostic
38
+ // if (!/^[a-z_0-9]+$/.test(c)) {
39
+ // console.error('invalid class detected, fix the regexps', c);
40
+ // }
41
+ continue;
42
+ }
43
+ if ('declaration' in v) {
44
+ css += `.${c} { ${v.declaration} }\n`;
45
+ } else {
46
+ css += v.ruleset + '\n';
47
+ }
48
+ }
49
+
50
+ return css;
51
+ };
52
+
53
+ const FLUSH_DEBOUNCE_DELAY = 500;
54
+
55
+ export interface Task_Args extends Args {
56
+ watch?: boolean;
57
+ }
58
+
59
+ export interface Options {
60
+ include_classes?: string[] | Set<string> | null;
61
+ outfile?: string;
62
+ filter_file?: File_Filter | null;
63
+ flush_debounce_delay?: number;
64
+ banner?: string;
65
+ }
66
+
67
+ export const gro_plugin_moss = ({
68
+ include_classes = null,
69
+ outfile = 'src/routes/moss.css', // TODO maybe support multiple files using file filters to check where to collect them?
70
+ filter_file = (p) => !p.includes('.test.') && !p.includes('/test/'),
71
+ flush_debounce_delay = FLUSH_DEBOUNCE_DELAY,
72
+ banner = 'generated by gro_plugin_moss',
73
+ }: Options = EMPTY_OBJECT): Plugin => {
74
+ const css_classes = new Css_Classes(
75
+ Array.isArray(include_classes) ? new Set(include_classes) : include_classes,
76
+ );
77
+
78
+ let previous_output: string | undefined;
79
+
80
+ let flushing_timeout: NodeJS.Timeout | undefined;
81
+ const queue_gen = () => {
82
+ if (flushing_timeout === undefined) {
83
+ flushing_timeout = setTimeout(() => {
84
+ flushing_timeout = undefined;
85
+ void flush_gen_queue();
86
+ }); // the timeout batches synchronously
87
+ }
88
+ };
89
+ const flush_gen_queue = throttle(
90
+ async () => {
91
+ const css = generate_classes_css(css_classes.get_sorted_array());
92
+ const contents = `/* ${banner} */\n\n${css}\n\n/* ${banner} */`;
93
+ const output = await format_file(contents, {filepath: outfile});
94
+ // TODO think about using gen to implement this, would have some nice benefits like automatic change detection
95
+ if (output === previous_output) return;
96
+ previous_output = output;
97
+ writeFileSync(outfile, output);
98
+ },
99
+ {delay: flush_debounce_delay, when: 'trailing'},
100
+ );
101
+
102
+ let cleanup: Cleanup_Watch | undefined;
103
+
104
+ return {
105
+ name: 'gro_plugin_moss',
106
+ setup: async ({filer}) => {
107
+ // When a file builds, check it and its tree of dependents
108
+ // for any `.gen.` files that need to run.
109
+ cleanup = await filer.watch((change, source_file) => {
110
+ if (filter_file && !filter_file(source_file.id)) {
111
+ return;
112
+ }
113
+ switch (change.type) {
114
+ case 'add':
115
+ case 'update': {
116
+ if (source_file.contents !== null) {
117
+ const classes = collect_css_classes(source_file.contents);
118
+ css_classes.add(source_file.id, classes);
119
+ queue_gen();
120
+ }
121
+ break;
122
+ }
123
+ case 'delete': {
124
+ css_classes.delete(source_file.id);
125
+ break;
126
+ }
127
+ default:
128
+ throw new Unreachable_Error(change.type);
129
+ }
130
+ });
131
+ queue_gen();
132
+ },
133
+ teardown: async () => {
134
+ if (cleanup !== undefined) {
135
+ await cleanup();
136
+ cleanup = undefined;
137
+ }
138
+ },
139
+ };
140
+ };
@@ -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}) => {
@@ -3,7 +3,7 @@ import {existsSync} from 'node:fs';
3
3
  import {resolve} from 'node:path';
4
4
 
5
5
  import {has_dep, type Package_Json} from './package_json.js';
6
- import {NODE_MODULES_DIRNAME, PM_CLI_DEFAULT} from './constants.js';
6
+ import {NODE_MODULES_DIRNAME} from './constants.js';
7
7
 
8
8
  export const MOSS_PACKAGE_DEP_NAME = '@ryanatkn/moss';
9
9
 
@@ -13,12 +13,11 @@ export const load_moss_plugin = async (
13
13
  dep_name = MOSS_PACKAGE_DEP_NAME,
14
14
  plugin_path = `${NODE_MODULES_DIRNAME}/${dep_name}/dist/gro_plugin_moss.js`, // TODO maybe lookup from its `package_json.exports`? kinda unnecessary
15
15
  local_plugin_path = 'src/lib/gro_plugin_moss.ts',
16
- pm_cli = PM_CLI_DEFAULT, // TODO source from config when possible, is just needed for error messages
17
16
  ): Promise<Result<{gro_plugin_moss: any}, {message: string}>> => {
18
17
  if (!has_dep(dep_name, package_json)) {
19
18
  return {
20
19
  ok: false,
21
- message: `no dependency found in package.json for ${dep_name}, install it with \`${pm_cli} install -D ${dep_name}\``,
20
+ message: `no dependency found in package.json for ${dep_name}`,
22
21
  };
23
22
  }
24
23