svelte-ag 1.0.18 → 1.0.20

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.
@@ -20,10 +20,12 @@ export type ApiRequestForm<API extends ApiEndpoints> = <Path extends API['path']
20
20
  method: Method;
21
21
  /**
22
22
  * Optional lifecycle hooks for consumers.
23
+ * - `beforeRequest`: called before sending the api call
23
24
  * - `onSuccess`: called after a successful response body is parsed.
24
25
  * - `onFail`: called after an error response body is parsed and mapped to form errors/messages.
25
26
  */
26
27
  actions?: {
28
+ beforeRequest?: (form: SuperValidated<ValidInput<API, Path, Method>>) => void | Promise<void>;
27
29
  onSuccess?: (form: SuperValidated<ValidInput<API, Path, Method>>, response: ApiSuccessBody<API, Path, Method>) => void | Promise<void>;
28
30
  onFail?: (form: SuperValidated<ValidInput<API, Path, Method>>, response: ApiErrorBody<API, Path, Method>) => void | Promise<void>;
29
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"form.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/api/form.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkC,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtH,OAAO,KAAK,EACV,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,SAAS,EACV,MAAM,OAAO,CAAC;AAMf,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,WAAW,CACtG,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAClB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,CAAC,GAAG,SAAS,YAAY,IAAI,CACrD,IAAI,SAAS,GAAG,CAAC,MAAM,CAAC,EACxB,MAAM,SAAS,OAAO,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC,QAAQ,CAAC,EACrD,CAAC,EAAE;IACH,qFAAqF;IACrF,IAAI,EAAE,IAAI,CAAC;IAEX,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,CACV,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,EACnD,QAAQ,EAAE,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,KACxC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,CACP,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,EACnD,QAAQ,EAAE,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,KACtC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3B,CAAC;IAEF;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAEpD;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,CAAC,EAAE;QACL;;;;;WAKG;QACH,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAE9E;;;WAGG;QACH,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;KACtD,CAAC;IAEF;;;OAGG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5E,KAAK,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/C;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,SAAS,YAAY,EACzD,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAC7E,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAC/B,cAAc,CAAC,GAAG,CAAC,CAqGrB"}
1
+ {"version":3,"file":"form.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/api/form.svelte.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { valibot } from 'sveltekit-superforms/adapters';
3
3
  import { watch } from 'runed';
4
4
  import { dequal } from 'dequal';
5
5
  import { get } from 'svelte/store';
6
- import { safeParseAsync } from 'valibot';
6
+ import { safeParse, safeParseAsync } from 'valibot';
7
7
  /**
8
8
  * Build an endpoint-specific Superforms factory.
9
9
  *
@@ -20,7 +20,11 @@ export function createFormFunction(schemas, request) {
20
20
  // if (typeof schema === 'function') {
21
21
  // schema = schema();
22
22
  // }
23
- const form = superForm(defaults(defaultValue, valibot(schema)), {
23
+ const defaultFormData = defaults(defaultValue, valibot(schema));
24
+ const boundFormData = bind && schema.async === false
25
+ ? safeParse(schema, bind.get(defaultFormData)).output
26
+ : defaultFormData;
27
+ const form = superForm(boundFormData, {
24
28
  SPA: true,
25
29
  resetForm: true,
26
30
  applyAction: false, // Prevents the form redirecting to the same page on submit
@@ -42,8 +46,11 @@ export function createFormFunction(schemas, request) {
42
46
  }
43
47
  },
44
48
  async onUpdate({ form }) {
49
+ if (actions && actions.beforeRequest)
50
+ actions.beforeRequest(form);
45
51
  if (!form.valid)
46
52
  return;
53
+ // console.log('onUpdate: sending data', form.data);
47
54
  const res = await request(path, method, form.data);
48
55
  if (res.ok === false) {
49
56
  const body = await res.json();
@@ -1,5 +1,5 @@
1
1
  import type { SearchProps } from '../types.js';
2
- declare const Search: import("svelte").Component<SearchProps, {}, "items" | "value" | "ref" | "searchWith">;
2
+ declare const Search: import("svelte").Component<SearchProps, {}, "value" | "items" | "ref" | "searchWith">;
3
3
  type Search = ReturnType<typeof Search>;
4
4
  export default Search;
5
5
  //# sourceMappingURL=search.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-component-source-collector.d.ts","sourceRoot":"","sources":["../../../src/lib/vite/vite-plugin-component-source-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AAKnD,UAAU,OAAO;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAKD,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,IAAI,GAAE,OAA8B,GAAG,MAAM,CAsH7F"}
1
+ {"version":3,"file":"vite-plugin-component-source-collector.d.ts","sourceRoot":"","sources":["../../../src/lib/vite/vite-plugin-component-source-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AAKnD,UAAU,OAAO;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAKD,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,IAAI,GAAE,OAA8B,GAAG,MAAM,CA4J7F"}
@@ -1,6 +1,6 @@
1
1
  import { exists, writeIfDifferent } from 'ts-ag';
2
2
  import { readFile } from 'fs/promises';
3
- import { resolve, relative, dirname } from 'path';
3
+ import { resolve, join, relative, dirname } from 'path';
4
4
  /** All unique component directories */
5
5
  const componentFiles = new Set();
6
6
  export default function componentSourceCollector(opts = { safePackages: [] }) {
@@ -8,6 +8,8 @@ export default function componentSourceCollector(opts = { safePackages: [] }) {
8
8
  const outFileName = opts.outputFile ?? 'component-sources.css';
9
9
  const classRegex = /class(?:=|:)/;
10
10
  const importRegex = /@import\s+['"]([^'"]+)['"]/g;
11
+ let outputFilePath = undefined;
12
+ let root = undefined;
11
13
  // state
12
14
  let config;
13
15
  let firstRound = true;
@@ -17,13 +19,17 @@ export default function componentSourceCollector(opts = { safePackages: [] }) {
17
19
  return classRegex.test(code);
18
20
  }
19
21
  function addPath(file) {
20
- if (file !== '' && // No nothing
22
+ if (outputFilePath &&
23
+ file !== '' && // No nothing
21
24
  !/\.svelte-kit/.test(file) && // No svelte-kit files
22
25
  // No dep files unless marked as safe
23
26
  (!/\.pnpm|.vite/.test(file) || opts.safePackages.some((p) => file.includes(`node_modules/${p}`)))) {
24
- const outPath = resolve(config.root, outFileName);
25
27
  const cleanedFileName = file.replace(/\?v=.*$/, '');
26
- componentFiles.add(relative(dirname(outPath), cleanedFileName));
28
+ const relativeFilePath = relative(dirname(outputFilePath), cleanedFileName);
29
+ if (relativeFilePath !== outputFilePath) {
30
+ // Dont add itself
31
+ componentFiles.add(relativeFilePath);
32
+ }
27
33
  }
28
34
  }
29
35
  function scheduleInitialWrite() {
@@ -37,34 +43,62 @@ export default function componentSourceCollector(opts = { safePackages: [] }) {
37
43
  }, 1000); // adjust delay as needed
38
44
  }
39
45
  const writeOutFile = async () => {
40
- const outPath = resolve(config.root, outFileName);
41
46
  const lines = Array.from(componentFiles)
42
47
  .map((d) => `@source '${d}';`)
43
48
  .sort();
44
- const didWrite = await writeIfDifferent(outPath, lines.join('\n'));
45
- if (didWrite)
46
- console.log('Wrote', lines.length);
49
+ if (outputFilePath) {
50
+ const didWrite = await writeIfDifferent(outputFilePath, lines.join('\n'));
51
+ if (didWrite)
52
+ console.log('Wrote', lines.length);
53
+ }
47
54
  };
48
55
  // ---- plugin ---- //
49
56
  return {
50
57
  name: 'vite-plugin-component-source-collector',
51
- enforce: 'post',
58
+ enforce: 'pre', // i want to see comments
59
+ /**
60
+ * Setup. Add exisitng files to internal state if dev
61
+ */
52
62
  async configResolved(resolved) {
53
63
  config = resolved;
54
- const outPath = resolve(config.root, outFileName);
64
+ root = config.root;
65
+ outputFilePath = resolve(root, outFileName);
55
66
  if (config.command === 'build' && firstRound) {
56
67
  componentFiles.clear();
57
68
  firstRound = false;
58
69
  }
59
70
  else if (config.command === 'serve') {
60
- if (await exists(outPath)) {
61
- const fileLines = (await readFile(outPath, 'utf8')).split('\n');
71
+ if (await exists(outputFilePath)) {
72
+ const fileLines = (await readFile(outputFilePath, 'utf8')).split('\n');
62
73
  fileLines.forEach((l) => addPath(l.replace(/@source\s+'(.*?)';/, '$1')));
63
74
  // console.log('config resolved', componentFiles);
64
75
  }
65
76
  }
66
77
  console.log('tailwind-sources:configResolved:command', config.command);
67
78
  },
79
+ /**
80
+ * Reset list on lock file changed
81
+ */
82
+ configureServer(server) {
83
+ const lockFiles = [
84
+ 'pnpm-lock.yaml',
85
+ 'package-lock.json',
86
+ 'yarn.lock',
87
+ 'bun.lockb',
88
+ 'bun.lock',
89
+ 'npm-shrinkwrap.json',
90
+ // pnpm install-state changes:
91
+ 'node_modules/.modules.yaml'
92
+ ].map((p) => join(root, p));
93
+ server.watcher.add(lockFiles);
94
+ const onChange = async (file) => {
95
+ if (!lockFiles.includes(file))
96
+ return;
97
+ componentFiles.clear();
98
+ };
99
+ server.watcher.on('change', onChange);
100
+ server.watcher.on('add', onChange);
101
+ },
68
102
  buildStart() {
69
103
  // console.log('tailwind-sources:buildStart', componentFiles);
70
104
  // componentFiles.clear();
@@ -76,9 +110,14 @@ export default function componentSourceCollector(opts = { safePackages: [] }) {
76
110
  const matches = code.matchAll(importRegex);
77
111
  for (const match of matches) {
78
112
  // console.log('MATching', match);
79
- const resolved = await this.resolve(match[1], id);
80
- if (resolved) {
81
- addPath(resolved.id);
113
+ try {
114
+ const resolved = await this.resolve(match[1], id);
115
+ if (resolved) {
116
+ addPath(resolved.id);
117
+ }
118
+ }
119
+ catch {
120
+ // Cant resolve: dont add
82
121
  }
83
122
  }
84
123
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-ag",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "Useful svelte components",
5
5
  "bugs": "https://github.com/ageorgeh/svelte-ag/issues",
6
6
  "repository": {
@@ -48,8 +48,7 @@
48
48
  "@dnd-kit-svelte/svelte": "^0.1.6",
49
49
  "@dnd-kit/helpers": "^0.2.4",
50
50
  "@floating-ui/dom": "^1.7.5",
51
- "@rollup/pluginutils": "^5.3.0",
52
- "@sveltejs/kit": "^2.52.2",
51
+ "@sveltejs/kit": "^2.53.0",
53
52
  "bits-ui": "^2.16.1",
54
53
  "bottleneck": "^2.19.5",
55
54
  "clsx": "^2.1.1",
@@ -64,7 +63,7 @@
64
63
  "sveltekit-superforms": "2.29.1",
65
64
  "tailwind-merge": "^3.5.0",
66
65
  "tailwind-variants": "^3.2.2",
67
- "ts-ag": "^1.0.10",
66
+ "ts-ag": "^1.0.11",
68
67
  "valibot": "^1.2.0"
69
68
  },
70
69
  "devDependencies": {
@@ -82,9 +81,8 @@
82
81
  "@tailwindcss/vite": "^4.2.0",
83
82
  "@types/node": "^24.10.13",
84
83
  "@typescript/native-preview": "7.0.0-dev.20260219.1",
85
- "eslint": "^10.0.0",
84
+ "eslint": "^10.0.1",
86
85
  "eslint-plugin-better-tailwindcss": "^4.3.0",
87
- "eslint-plugin-import": "^2.32.0",
88
86
  "eslint-plugin-svelte": "^3.15.0",
89
87
  "globals": "^17.3.0",
90
88
  "husky": "^9.1.7",
@@ -92,15 +90,14 @@
92
90
  "prettier": "^3.8.1",
93
91
  "prettier-plugin-packagejson": "^3.0.0",
94
92
  "prettier-plugin-svelte": "^3.5.0",
95
- "rollup": "^4.57.1",
96
93
  "semantic-release": "^25.0.3",
97
- "svelte-check": "^4.4.1",
94
+ "svelte-check": "^4.4.3",
98
95
  "tailwindcss": "4.2.0",
99
96
  "tw-animate-css": "^1.4.0",
100
97
  "typescript": "^5.9.3",
101
98
  "typescript-eslint": "^8.56.0",
102
99
  "typescript-svelte-plugin": "^0.3.50",
103
- "vite": "^7.3.1",
100
+ "vite": "^8.0.0-beta.15",
104
101
  "vitest": "^4.0.18"
105
102
  },
106
103
  "peerDependencies": {
@@ -113,6 +110,8 @@
113
110
  "esbuild",
114
111
  "@tailwindcss/oxide"
115
112
  ],
116
- "overrides": {}
113
+ "overrides": {
114
+ "vite": "8.0.0-beta.15"
115
+ }
117
116
  }
118
117
  }
@@ -12,7 +12,7 @@ import type {
12
12
  import { watch } from 'runed';
13
13
  import { dequal } from 'dequal';
14
14
  import { get } from 'svelte/store';
15
- import { safeParseAsync } from 'valibot';
15
+ import { safeParse, safeParseAsync } from 'valibot';
16
16
 
17
17
  export type ValidInput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = NonNullable<
18
18
  ApiInput<E, P, M>
@@ -40,10 +40,12 @@ export type ApiRequestForm<API extends ApiEndpoints> = <
40
40
 
41
41
  /**
42
42
  * Optional lifecycle hooks for consumers.
43
+ * - `beforeRequest`: called before sending the api call
43
44
  * - `onSuccess`: called after a successful response body is parsed.
44
45
  * - `onFail`: called after an error response body is parsed and mapped to form errors/messages.
45
46
  */
46
47
  actions?: {
48
+ beforeRequest?: (form: SuperValidated<ValidInput<API, Path, Method>>) => void | Promise<void>;
47
49
  onSuccess?: (
48
50
  form: SuperValidated<ValidInput<API, Path, Method>>,
49
51
  response: ApiSuccessBody<API, Path, Method>
@@ -121,7 +123,13 @@ export function createFormFunction<API extends ApiEndpoints>(
121
123
  // schema = schema();
122
124
  // }
123
125
 
124
- const form = superForm<ValidInput<API, typeof path, typeof method>>(defaults(defaultValue, valibot(schema)), {
126
+ const defaultFormData = defaults(defaultValue, valibot(schema));
127
+ const boundFormData =
128
+ bind && schema.async === false
129
+ ? (safeParse(schema, bind.get(defaultFormData)).output as ValidInput<API, typeof path, typeof method>)
130
+ : defaultFormData;
131
+
132
+ const form = superForm<ValidInput<API, typeof path, typeof method>>(boundFormData, {
125
133
  SPA: true,
126
134
  resetForm: true,
127
135
  applyAction: false, // Prevents the form redirecting to the same page on submit
@@ -145,8 +153,11 @@ export function createFormFunction<API extends ApiEndpoints>(
145
153
  }
146
154
  },
147
155
  async onUpdate({ form }) {
156
+ if (actions && actions.beforeRequest) actions.beforeRequest(form);
157
+
148
158
  if (!form.valid) return;
149
159
 
160
+ // console.log('onUpdate: sending data', form.data);
150
161
  const res = await request(path, method, form.data);
151
162
 
152
163
  if (res.ok === false) {
@@ -1,7 +1,7 @@
1
1
  import type { Plugin, ResolvedConfig } from 'vite';
2
2
  import { exists, writeIfDifferent } from 'ts-ag';
3
3
  import { readFile } from 'fs/promises';
4
- import { resolve, relative, dirname } from 'path';
4
+ import { resolve, join, relative, dirname } from 'path';
5
5
 
6
6
  interface Options {
7
7
  /**
@@ -29,6 +29,9 @@ export default function componentSourceCollector(opts: Options = { safePackages:
29
29
  const classRegex = /class(?:=|:)/;
30
30
  const importRegex = /@import\s+['"]([^'"]+)['"]/g;
31
31
 
32
+ let outputFilePath: string | undefined = undefined;
33
+ let root: string | undefined = undefined;
34
+
32
35
  // state
33
36
  let config: ResolvedConfig;
34
37
  let firstRound = true;
@@ -41,15 +44,19 @@ export default function componentSourceCollector(opts: Options = { safePackages:
41
44
 
42
45
  function addPath(file: string) {
43
46
  if (
47
+ outputFilePath &&
44
48
  file !== '' && // No nothing
45
49
  !/\.svelte-kit/.test(file) && // No svelte-kit files
46
50
  // No dep files unless marked as safe
47
51
  (!/\.pnpm|.vite/.test(file) || opts.safePackages.some((p) => file.includes(`node_modules/${p}`)))
48
52
  ) {
49
- const outPath = resolve(config.root, outFileName);
50
53
  const cleanedFileName = file.replace(/\?v=.*$/, '');
54
+ const relativeFilePath = relative(dirname(outputFilePath), cleanedFileName);
51
55
 
52
- componentFiles.add(relative(dirname(outPath), cleanedFileName));
56
+ if (relativeFilePath !== outputFilePath) {
57
+ // Dont add itself
58
+ componentFiles.add(relativeFilePath);
59
+ }
53
60
  }
54
61
  }
55
62
 
@@ -64,32 +71,36 @@ export default function componentSourceCollector(opts: Options = { safePackages:
64
71
  }
65
72
 
66
73
  const writeOutFile = async () => {
67
- const outPath = resolve(config.root, outFileName);
68
-
69
74
  const lines = Array.from(componentFiles)
70
75
  .map((d) => `@source '${d}';`)
71
76
  .sort();
72
77
 
73
- const didWrite = await writeIfDifferent(outPath, lines.join('\n'));
74
- if (didWrite) console.log('Wrote', lines.length);
78
+ if (outputFilePath) {
79
+ const didWrite = await writeIfDifferent(outputFilePath, lines.join('\n'));
80
+ if (didWrite) console.log('Wrote', lines.length);
81
+ }
75
82
  };
76
83
 
77
84
  // ---- plugin ---- //
78
85
 
79
86
  return {
80
87
  name: 'vite-plugin-component-source-collector',
81
- enforce: 'post',
88
+ enforce: 'pre', // i want to see comments
82
89
 
90
+ /**
91
+ * Setup. Add exisitng files to internal state if dev
92
+ */
83
93
  async configResolved(resolved) {
84
94
  config = resolved;
85
- const outPath = resolve(config.root, outFileName);
95
+ root = config.root;
96
+ outputFilePath = resolve(root, outFileName);
86
97
 
87
98
  if (config.command === 'build' && firstRound) {
88
99
  componentFiles.clear();
89
100
  firstRound = false;
90
101
  } else if (config.command === 'serve') {
91
- if (await exists(outPath)) {
92
- const fileLines = (await readFile(outPath, 'utf8')).split('\n');
102
+ if (await exists(outputFilePath)) {
103
+ const fileLines = (await readFile(outputFilePath, 'utf8')).split('\n');
93
104
  fileLines.forEach((l) => addPath(l.replace(/@source\s+'(.*?)';/, '$1')));
94
105
  // console.log('config resolved', componentFiles);
95
106
  }
@@ -97,6 +108,29 @@ export default function componentSourceCollector(opts: Options = { safePackages:
97
108
  console.log('tailwind-sources:configResolved:command', config.command);
98
109
  },
99
110
 
111
+ /**
112
+ * Reset list on lock file changed
113
+ */
114
+ configureServer(server) {
115
+ const lockFiles = [
116
+ 'pnpm-lock.yaml',
117
+ 'package-lock.json',
118
+ 'yarn.lock',
119
+ 'bun.lockb',
120
+ 'bun.lock',
121
+ 'npm-shrinkwrap.json',
122
+ // pnpm install-state changes:
123
+ 'node_modules/.modules.yaml'
124
+ ].map((p) => join(root!, p));
125
+ server.watcher.add(lockFiles);
126
+ const onChange = async (file: string) => {
127
+ if (!lockFiles.includes(file)) return;
128
+ componentFiles.clear();
129
+ };
130
+ server.watcher.on('change', onChange);
131
+ server.watcher.on('add', onChange);
132
+ },
133
+
100
134
  buildStart() {
101
135
  // console.log('tailwind-sources:buildStart', componentFiles);
102
136
  // componentFiles.clear();
@@ -110,9 +144,13 @@ export default function componentSourceCollector(opts: Options = { safePackages:
110
144
 
111
145
  for (const match of matches) {
112
146
  // console.log('MATching', match);
113
- const resolved = await this.resolve(match[1], id);
114
- if (resolved) {
115
- addPath(resolved.id);
147
+ try {
148
+ const resolved = await this.resolve(match[1], id);
149
+ if (resolved) {
150
+ addPath(resolved.id);
151
+ }
152
+ } catch {
153
+ // Cant resolve: dont add
116
154
  }
117
155
  }
118
156
  }