Tighten plugin dev file watching
This commit is contained in:
352
pnpm-lock.yaml
generated
352
pnpm-lock.yaml
generated
@@ -246,6 +246,180 @@ importers:
|
||||
specifier: ^3.0.5
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)
|
||||
|
||||
packages/plugins/create-paperclip-plugin:
|
||||
dependencies:
|
||||
'@paperclipai/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../sdk
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.6.0
|
||||
version: 24.12.0
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.9.3
|
||||
|
||||
packages/plugins/examples/plugin-authoring-smoke-example:
|
||||
dependencies:
|
||||
'@paperclipai/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../../sdk
|
||||
react:
|
||||
specifier: '>=18'
|
||||
version: 19.2.4
|
||||
devDependencies:
|
||||
'@rollup/plugin-node-resolve':
|
||||
specifier: ^16.0.1
|
||||
version: 16.0.3(rollup@4.57.1)
|
||||
'@rollup/plugin-typescript':
|
||||
specifier: ^12.1.2
|
||||
version: 12.3.0(rollup@4.57.1)(tslib@2.8.1)(typescript@5.9.3)
|
||||
'@types/node':
|
||||
specifier: ^24.6.0
|
||||
version: 24.12.0
|
||||
'@types/react':
|
||||
specifier: ^19.0.8
|
||||
version: 19.2.14
|
||||
esbuild:
|
||||
specifier: ^0.27.3
|
||||
version: 0.27.3
|
||||
rollup:
|
||||
specifier: ^4.38.0
|
||||
version: 4.57.1
|
||||
tslib:
|
||||
specifier: ^2.8.1
|
||||
version: 2.8.1
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^3.0.5
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)
|
||||
|
||||
packages/plugins/examples/plugin-file-browser-example:
|
||||
dependencies:
|
||||
'@codemirror/lang-javascript':
|
||||
specifier: ^6.2.2
|
||||
version: 6.2.4
|
||||
'@codemirror/language':
|
||||
specifier: ^6.11.0
|
||||
version: 6.12.1
|
||||
'@codemirror/state':
|
||||
specifier: ^6.4.0
|
||||
version: 6.5.4
|
||||
'@codemirror/view':
|
||||
specifier: ^6.28.0
|
||||
version: 6.39.15
|
||||
'@lezer/highlight':
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.3
|
||||
'@paperclipai/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../../sdk
|
||||
codemirror:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.2
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.6.0
|
||||
version: 24.12.0
|
||||
'@types/react':
|
||||
specifier: ^19.0.8
|
||||
version: 19.2.14
|
||||
'@types/react-dom':
|
||||
specifier: ^19.0.3
|
||||
version: 19.2.3(@types/react@19.2.14)
|
||||
esbuild:
|
||||
specifier: ^0.27.3
|
||||
version: 0.27.3
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4
|
||||
react-dom:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4(react@19.2.4)
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.9.3
|
||||
|
||||
packages/plugins/examples/plugin-hello-world-example:
|
||||
dependencies:
|
||||
'@paperclipai/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../../sdk
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.6.0
|
||||
version: 24.12.0
|
||||
'@types/react':
|
||||
specifier: ^19.0.8
|
||||
version: 19.2.14
|
||||
'@types/react-dom':
|
||||
specifier: ^19.0.3
|
||||
version: 19.2.3(@types/react@19.2.14)
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4
|
||||
react-dom:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4(react@19.2.4)
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.9.3
|
||||
|
||||
packages/plugins/examples/plugin-kitchen-sink-example:
|
||||
dependencies:
|
||||
'@paperclipai/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../../sdk
|
||||
'@paperclipai/shared':
|
||||
specifier: workspace:*
|
||||
version: link:../../../shared
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.6.0
|
||||
version: 24.12.0
|
||||
'@types/react':
|
||||
specifier: ^19.0.8
|
||||
version: 19.2.14
|
||||
'@types/react-dom':
|
||||
specifier: ^19.0.3
|
||||
version: 19.2.3(@types/react@19.2.14)
|
||||
esbuild:
|
||||
specifier: ^0.27.3
|
||||
version: 0.27.3
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4
|
||||
react-dom:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4(react@19.2.4)
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.9.3
|
||||
|
||||
packages/plugins/sdk:
|
||||
dependencies:
|
||||
'@paperclipai/shared':
|
||||
specifier: workspace:*
|
||||
version: link:../../shared
|
||||
react:
|
||||
specifier: '>=18'
|
||||
version: 19.2.4
|
||||
zod:
|
||||
specifier: ^3.24.2
|
||||
version: 3.25.76
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^24.6.0
|
||||
version: 24.12.0
|
||||
'@types/react':
|
||||
specifier: ^19.0.8
|
||||
version: 19.2.14
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.9.3
|
||||
|
||||
packages/shared:
|
||||
dependencies:
|
||||
zod:
|
||||
@@ -288,12 +462,24 @@ importers:
|
||||
'@paperclipai/db':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/db
|
||||
'@paperclipai/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/plugins/sdk
|
||||
'@paperclipai/shared':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/shared
|
||||
ajv:
|
||||
specifier: ^8.18.0
|
||||
version: 8.18.0
|
||||
ajv-formats:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1(ajv@8.18.0)
|
||||
better-auth:
|
||||
specifier: 1.4.18
|
||||
version: 1.4.18(drizzle-kit@0.31.9)(drizzle-orm@0.38.4(@electric-sql/pglite@0.3.15)(@types/react@19.2.14)(kysely@0.28.11)(pg@8.18.0)(postgres@3.4.8)(react@19.2.4))(pg@8.18.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))
|
||||
chokidar:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
detect-port:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
@@ -2436,6 +2622,37 @@ packages:
|
||||
'@rolldown/pluginutils@1.0.0-beta.27':
|
||||
resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==}
|
||||
|
||||
'@rollup/plugin-node-resolve@16.0.3':
|
||||
resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^2.78.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/plugin-typescript@12.3.0':
|
||||
resolution: {integrity: sha512-7DP0/p7y3t67+NabT9f8oTBFE6gGkto4SA6Np2oudYmZE/m1dt8RB0SjL1msMxFpLo631qjRCcBlAbq1ml/Big==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^2.14.0||^3.0.0||^4.0.0
|
||||
tslib: '*'
|
||||
typescript: '>=3.7.0'
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
tslib:
|
||||
optional: true
|
||||
|
||||
'@rollup/pluginutils@5.3.0':
|
||||
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.57.1':
|
||||
resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==}
|
||||
cpu: [arm]
|
||||
@@ -3068,6 +3285,9 @@ packages:
|
||||
'@types/react@19.2.14':
|
||||
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
|
||||
|
||||
'@types/resolve@1.20.2':
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
||||
'@types/send@1.2.1':
|
||||
resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==}
|
||||
|
||||
@@ -3148,6 +3368,17 @@ packages:
|
||||
resolution: {integrity: sha512-XNAb/a6TCqou+TufU8/u11HCu9x1gYvOoxLwtlXgIqmkrYQADVv6ljyW2zwiPhHz9R1gItAWpuDrdJMmrOBFEA==}
|
||||
engines: {node: '>= 16.0.0'}
|
||||
|
||||
ajv-formats@3.0.1:
|
||||
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
|
||||
peerDependencies:
|
||||
ajv: ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
ajv:
|
||||
optional: true
|
||||
|
||||
ajv@8.18.0:
|
||||
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
|
||||
|
||||
anser@2.3.5:
|
||||
resolution: {integrity: sha512-vcZjxvvVoxTeR5XBNJB38oTu/7eDCZlwdz32N1eNgpyPF7j/Z7Idf+CUwQOkKKpJ7RJyjxgLHCM7vdIK0iCNMQ==}
|
||||
|
||||
@@ -3361,6 +3592,10 @@ packages:
|
||||
chevrotain@11.1.2:
|
||||
resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==}
|
||||
|
||||
chokidar@4.0.3:
|
||||
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
||||
engines: {node: '>= 14.16.0'}
|
||||
|
||||
class-variance-authority@0.7.1:
|
||||
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
||||
|
||||
@@ -3660,6 +3895,10 @@ packages:
|
||||
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
deepmerge@4.3.1:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
default-browser-id@5.0.1:
|
||||
resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -3941,6 +4180,9 @@ packages:
|
||||
estree-util-visit@2.0.0:
|
||||
resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
|
||||
|
||||
estree-walker@2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
estree-walker@3.0.3:
|
||||
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
|
||||
|
||||
@@ -3971,6 +4213,9 @@ packages:
|
||||
fast-copy@4.0.2:
|
||||
resolution: {integrity: sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==}
|
||||
|
||||
fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
|
||||
fast-glob@3.3.3:
|
||||
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
@@ -3978,6 +4223,9 @@ packages:
|
||||
fast-safe-stringify@2.1.1:
|
||||
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
|
||||
|
||||
fast-uri@3.1.0:
|
||||
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
|
||||
|
||||
fast-xml-parser@5.3.6:
|
||||
resolution: {integrity: sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==}
|
||||
hasBin: true
|
||||
@@ -4165,6 +4413,10 @@ packages:
|
||||
is-alphanumerical@2.0.1:
|
||||
resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
|
||||
|
||||
is-core-module@2.16.1:
|
||||
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-decimal@2.0.1:
|
||||
resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
|
||||
|
||||
@@ -4193,6 +4445,9 @@ packages:
|
||||
engines: {node: '>=14.16'}
|
||||
hasBin: true
|
||||
|
||||
is-module@1.0.0:
|
||||
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
|
||||
|
||||
is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
@@ -4252,6 +4507,9 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
|
||||
json5@2.2.3:
|
||||
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -4742,6 +5000,9 @@ packages:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
|
||||
path-to-regexp@8.3.0:
|
||||
resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
|
||||
|
||||
@@ -5030,6 +5291,10 @@ packages:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
readdirp@4.1.2:
|
||||
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
||||
engines: {node: '>= 14.18.0'}
|
||||
|
||||
real-require@0.2.0:
|
||||
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
@@ -5046,6 +5311,10 @@ packages:
|
||||
remark-stringify@11.0.0:
|
||||
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
||||
|
||||
require-from-string@2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
resolve-from@5.0.0:
|
||||
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -5053,6 +5322,11 @@ packages:
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
resolve@1.22.11:
|
||||
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
hasBin: true
|
||||
|
||||
reusify@1.1.0:
|
||||
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
@@ -5257,6 +5531,10 @@ packages:
|
||||
resolution: {integrity: sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==}
|
||||
engines: {node: '>=14.18.0'}
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
tabbable@6.4.0:
|
||||
resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==}
|
||||
|
||||
@@ -8212,6 +8490,33 @@ snapshots:
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.27': {}
|
||||
|
||||
'@rollup/plugin-node-resolve@16.0.3(rollup@4.57.1)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.57.1)
|
||||
'@types/resolve': 1.20.2
|
||||
deepmerge: 4.3.1
|
||||
is-module: 1.0.0
|
||||
resolve: 1.22.11
|
||||
optionalDependencies:
|
||||
rollup: 4.57.1
|
||||
|
||||
'@rollup/plugin-typescript@12.3.0(rollup@4.57.1)(tslib@2.8.1)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.57.1)
|
||||
resolve: 1.22.11
|
||||
typescript: 5.9.3
|
||||
optionalDependencies:
|
||||
rollup: 4.57.1
|
||||
tslib: 2.8.1
|
||||
|
||||
'@rollup/pluginutils@5.3.0(rollup@4.57.1)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.3
|
||||
optionalDependencies:
|
||||
rollup: 4.57.1
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.57.1':
|
||||
optional: true
|
||||
|
||||
@@ -8934,6 +9239,8 @@ snapshots:
|
||||
dependencies:
|
||||
csstype: 3.2.3
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
'@types/send@1.2.1':
|
||||
dependencies:
|
||||
'@types/node': 25.2.3
|
||||
@@ -9043,6 +9350,17 @@ snapshots:
|
||||
|
||||
address@2.0.3: {}
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.18.0):
|
||||
optionalDependencies:
|
||||
ajv: 8.18.0
|
||||
|
||||
ajv@8.18.0:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-uri: 3.1.0
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
|
||||
anser@2.3.5: {}
|
||||
|
||||
ansi-colors@4.1.3: {}
|
||||
@@ -9209,6 +9527,10 @@ snapshots:
|
||||
'@chevrotain/utils': 11.1.2
|
||||
lodash-es: 4.17.23
|
||||
|
||||
chokidar@4.0.3:
|
||||
dependencies:
|
||||
readdirp: 4.1.2
|
||||
|
||||
class-variance-authority@0.7.1:
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
@@ -9517,6 +9839,8 @@ snapshots:
|
||||
|
||||
deep-eql@5.0.2: {}
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
default-browser-id@5.0.1: {}
|
||||
|
||||
default-browser@5.5.0:
|
||||
@@ -9789,6 +10113,8 @@ snapshots:
|
||||
'@types/estree-jsx': 1.0.5
|
||||
'@types/unist': 3.0.3
|
||||
|
||||
estree-walker@2.0.2: {}
|
||||
|
||||
estree-walker@3.0.3:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@@ -9845,6 +10171,8 @@ snapshots:
|
||||
|
||||
fast-copy@4.0.2: {}
|
||||
|
||||
fast-deep-equal@3.1.3: {}
|
||||
|
||||
fast-glob@3.3.3:
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@@ -9855,6 +10183,8 @@ snapshots:
|
||||
|
||||
fast-safe-stringify@2.1.1: {}
|
||||
|
||||
fast-uri@3.1.0: {}
|
||||
|
||||
fast-xml-parser@5.3.6:
|
||||
dependencies:
|
||||
strnum: 2.1.2
|
||||
@@ -10057,6 +10387,10 @@ snapshots:
|
||||
is-alphabetical: 2.0.1
|
||||
is-decimal: 2.0.1
|
||||
|
||||
is-core-module@2.16.1:
|
||||
dependencies:
|
||||
hasown: 2.0.2
|
||||
|
||||
is-decimal@2.0.1: {}
|
||||
|
||||
is-docker@3.0.0: {}
|
||||
@@ -10075,6 +10409,8 @@ snapshots:
|
||||
dependencies:
|
||||
is-docker: 3.0.0
|
||||
|
||||
is-module@1.0.0: {}
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
is-plain-obj@4.1.0: {}
|
||||
@@ -10116,6 +10452,8 @@ snapshots:
|
||||
|
||||
jsesc@3.1.0: {}
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
|
||||
json5@2.2.3: {}
|
||||
|
||||
jsonfile@4.0.0:
|
||||
@@ -10873,6 +11211,8 @@ snapshots:
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
|
||||
path-to-regexp@8.3.0: {}
|
||||
|
||||
path-type@4.0.0: {}
|
||||
@@ -11221,6 +11561,8 @@ snapshots:
|
||||
string_decoder: 1.3.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
readdirp@4.1.2: {}
|
||||
|
||||
real-require@0.2.0: {}
|
||||
|
||||
remark-gfm@4.0.1:
|
||||
@@ -11257,10 +11599,18 @@ snapshots:
|
||||
mdast-util-to-markdown: 2.1.2
|
||||
unified: 11.0.5
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
resolve-from@5.0.0: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
resolve@1.22.11:
|
||||
dependencies:
|
||||
is-core-module: 2.16.1
|
||||
path-parse: 1.0.7
|
||||
supports-preserve-symlinks-flag: 1.0.0
|
||||
|
||||
reusify@1.1.0: {}
|
||||
|
||||
robust-predicates@3.0.2: {}
|
||||
@@ -11510,6 +11860,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
tabbable@6.4.0: {}
|
||||
|
||||
tailwind-merge@3.4.1: {}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"ajv": "^8.18.0",
|
||||
"ajv-formats": "^3.0.1",
|
||||
"better-auth": "1.4.18",
|
||||
"chokidar": "^4.0.3",
|
||||
"detect-port": "^2.1.0",
|
||||
"dotenv": "^17.0.1",
|
||||
"drizzle-orm": "^0.38.4",
|
||||
|
||||
@@ -20,7 +20,7 @@ function makeTempPluginDir(): string {
|
||||
}
|
||||
|
||||
describe("resolvePluginWatchTargets", () => {
|
||||
it("watches the package root plus declared build output directories", () => {
|
||||
it("watches package metadata plus concrete declared runtime files", () => {
|
||||
const pluginDir = makeTempPluginDir();
|
||||
mkdirSync(path.join(pluginDir, "dist", "ui"), { recursive: true });
|
||||
writeFileSync(
|
||||
@@ -37,26 +37,32 @@ describe("resolvePluginWatchTargets", () => {
|
||||
writeFileSync(path.join(pluginDir, "dist", "manifest.js"), "export default {};\n");
|
||||
writeFileSync(path.join(pluginDir, "dist", "worker.js"), "export default {};\n");
|
||||
writeFileSync(path.join(pluginDir, "dist", "ui", "index.js"), "export default {};\n");
|
||||
writeFileSync(path.join(pluginDir, "dist", "ui", "index.css"), "body {}\n");
|
||||
|
||||
const targets = resolvePluginWatchTargets(pluginDir);
|
||||
|
||||
expect(targets).toEqual([
|
||||
{ path: pluginDir, recursive: false },
|
||||
{ path: path.join(pluginDir, "dist"), recursive: true },
|
||||
{ path: path.join(pluginDir, "dist", "ui"), recursive: true },
|
||||
{ path: path.join(pluginDir, "dist", "manifest.js"), recursive: false, kind: "file" },
|
||||
{ path: path.join(pluginDir, "dist", "ui", "index.css"), recursive: false, kind: "file" },
|
||||
{ path: path.join(pluginDir, "dist", "ui", "index.js"), recursive: false, kind: "file" },
|
||||
{ path: path.join(pluginDir, "dist", "worker.js"), recursive: false, kind: "file" },
|
||||
{ path: path.join(pluginDir, "package.json"), recursive: false, kind: "file" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("falls back to dist when package metadata does not declare entrypoints", () => {
|
||||
const pluginDir = makeTempPluginDir();
|
||||
mkdirSync(path.join(pluginDir, "dist"), { recursive: true });
|
||||
mkdirSync(path.join(pluginDir, "dist", "nested"), { recursive: true });
|
||||
writeFileSync(path.join(pluginDir, "package.json"), JSON.stringify({ name: "@acme/example" }));
|
||||
writeFileSync(path.join(pluginDir, "dist", "manifest.js"), "export default {};\n");
|
||||
writeFileSync(path.join(pluginDir, "dist", "nested", "chunk.js"), "export default {};\n");
|
||||
|
||||
const targets = resolvePluginWatchTargets(pluginDir);
|
||||
|
||||
expect(targets).toEqual([
|
||||
{ path: pluginDir, recursive: false },
|
||||
{ path: path.join(pluginDir, "dist"), recursive: true },
|
||||
{ path: path.join(pluginDir, "package.json"), recursive: false, kind: "file" },
|
||||
{ path: path.join(pluginDir, "dist", "manifest.js"), recursive: false, kind: "file" },
|
||||
{ path: path.join(pluginDir, "dist", "nested", "chunk.js"), recursive: false, kind: "file" },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -272,14 +272,16 @@ export async function createApp(
|
||||
void toolDispatcher.initialize().catch((err) => {
|
||||
logger.error({ err }, "Failed to initialize plugin tool dispatcher");
|
||||
});
|
||||
const devWatcher = createPluginDevWatcher(
|
||||
lifecycle,
|
||||
async (pluginId) => (await pluginRegistry.getById(pluginId))?.packagePath ?? null,
|
||||
);
|
||||
const devWatcher = opts.uiMode === "vite-dev"
|
||||
? createPluginDevWatcher(
|
||||
lifecycle,
|
||||
async (pluginId) => (await pluginRegistry.getById(pluginId))?.packagePath ?? null,
|
||||
)
|
||||
: null;
|
||||
void loader.loadAll().then((result) => {
|
||||
if (!result) return;
|
||||
for (const loaded of result.results) {
|
||||
if (loaded.success && loaded.plugin.packagePath) {
|
||||
if (devWatcher && loaded.success && loaded.plugin.packagePath) {
|
||||
devWatcher.watch(loaded.plugin.id, loaded.plugin.packagePath);
|
||||
}
|
||||
}
|
||||
@@ -287,7 +289,7 @@ export async function createApp(
|
||||
logger.error({ err }, "Failed to load ready plugins on startup");
|
||||
});
|
||||
process.once("exit", () => {
|
||||
devWatcher.close();
|
||||
devWatcher?.close();
|
||||
hostServiceCleanup.disposeAll();
|
||||
hostServiceCleanup.teardown();
|
||||
});
|
||||
|
||||
@@ -7,10 +7,14 @@
|
||||
* `packagePath` in the DB) are watched. File changes in the plugin's package
|
||||
* directory trigger a debounced worker restart via the lifecycle manager.
|
||||
*
|
||||
* Uses chokidar rather than raw fs.watch so we get a production-grade watcher
|
||||
* backend across platforms and avoid exhausting file descriptors as quickly in
|
||||
* large dev workspaces.
|
||||
*
|
||||
* @see PLUGIN_SPEC.md §27.2 — Local Development Workflow
|
||||
*/
|
||||
import { watch, type FSWatcher } from "node:fs";
|
||||
import { existsSync, readFileSync, statSync } from "node:fs";
|
||||
import chokidar, { type FSWatcher } from "chokidar";
|
||||
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { logger } from "../middleware/logger.js";
|
||||
import type { PluginLifecycleManager } from "./plugin-lifecycle.js";
|
||||
@@ -35,14 +39,15 @@ export type ResolvePluginPackagePath = (
|
||||
|
||||
export interface PluginDevWatcherFsDeps {
|
||||
existsSync?: typeof existsSync;
|
||||
watch?: typeof watch;
|
||||
readFileSync?: typeof readFileSync;
|
||||
readdirSync?: typeof readdirSync;
|
||||
statSync?: typeof statSync;
|
||||
}
|
||||
|
||||
type PluginWatchTarget = {
|
||||
path: string;
|
||||
recursive: boolean;
|
||||
kind: "file" | "dir";
|
||||
};
|
||||
|
||||
type PluginPackageJson = {
|
||||
@@ -69,17 +74,19 @@ function shouldIgnorePath(filename: string | null | undefined): boolean {
|
||||
|
||||
export function resolvePluginWatchTargets(
|
||||
packagePath: string,
|
||||
fsDeps?: Pick<PluginDevWatcherFsDeps, "existsSync" | "readFileSync" | "statSync">,
|
||||
fsDeps?: Pick<PluginDevWatcherFsDeps, "existsSync" | "readFileSync" | "readdirSync" | "statSync">,
|
||||
): PluginWatchTarget[] {
|
||||
const fileExists = fsDeps?.existsSync ?? existsSync;
|
||||
const readFile = fsDeps?.readFileSync ?? readFileSync;
|
||||
const readDir = fsDeps?.readdirSync ?? readdirSync;
|
||||
const statFile = fsDeps?.statSync ?? statSync;
|
||||
const absPath = path.resolve(packagePath);
|
||||
const targets = new Map<string, PluginWatchTarget>();
|
||||
|
||||
function addWatchTarget(targetPath: string, recursive: boolean): void {
|
||||
function addWatchTarget(targetPath: string, recursive: boolean, kind?: "file" | "dir"): void {
|
||||
const resolved = path.resolve(targetPath);
|
||||
if (!fileExists(resolved)) return;
|
||||
const inferredKind = kind ?? (statFile(resolved).isDirectory() ? "dir" : "file");
|
||||
|
||||
const existing = targets.get(resolved);
|
||||
if (existing) {
|
||||
@@ -87,14 +94,27 @@ export function resolvePluginWatchTargets(
|
||||
return;
|
||||
}
|
||||
|
||||
targets.set(resolved, { path: resolved, recursive });
|
||||
targets.set(resolved, { path: resolved, recursive, kind: inferredKind });
|
||||
}
|
||||
|
||||
// Watch the package root non-recursively so top-level files like package.json
|
||||
// can trigger reloads without traversing node_modules or other deep trees.
|
||||
addWatchTarget(absPath, false);
|
||||
function addRuntimeFilesFromDir(dirPath: string): void {
|
||||
if (!fileExists(dirPath)) return;
|
||||
|
||||
for (const entry of readDir(dirPath, { withFileTypes: true })) {
|
||||
const entryPath = path.join(dirPath, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
addRuntimeFilesFromDir(entryPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry.isFile()) continue;
|
||||
if (!entry.name.endsWith(".js") && !entry.name.endsWith(".css")) continue;
|
||||
addWatchTarget(entryPath, false, "file");
|
||||
}
|
||||
}
|
||||
|
||||
const packageJsonPath = path.join(absPath, "package.json");
|
||||
addWatchTarget(packageJsonPath, false, "file");
|
||||
if (!fileExists(packageJsonPath)) {
|
||||
return [...targets.values()];
|
||||
}
|
||||
@@ -113,7 +133,7 @@ export function resolvePluginWatchTargets(
|
||||
].filter((value): value is string => typeof value === "string" && value.length > 0);
|
||||
|
||||
if (entrypointPaths.length === 0) {
|
||||
addWatchTarget(path.join(absPath, "dist"), true);
|
||||
addRuntimeFilesFromDir(path.join(absPath, "dist"));
|
||||
return [...targets.values()];
|
||||
}
|
||||
|
||||
@@ -123,13 +143,13 @@ export function resolvePluginWatchTargets(
|
||||
|
||||
const stat = statFile(resolvedEntrypoint);
|
||||
if (stat.isDirectory()) {
|
||||
addWatchTarget(resolvedEntrypoint, true);
|
||||
addRuntimeFilesFromDir(resolvedEntrypoint);
|
||||
} else {
|
||||
addWatchTarget(path.dirname(resolvedEntrypoint), true);
|
||||
addWatchTarget(resolvedEntrypoint, false, "file");
|
||||
}
|
||||
}
|
||||
|
||||
return [...targets.values()];
|
||||
return [...targets.values()].sort((a, b) => a.path.localeCompare(b.path));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,10 +161,9 @@ export function createPluginDevWatcher(
|
||||
resolvePluginPackagePath?: ResolvePluginPackagePath,
|
||||
fsDeps?: PluginDevWatcherFsDeps,
|
||||
): PluginDevWatcher {
|
||||
const watchers = new Map<string, FSWatcher[]>();
|
||||
const watchers = new Map<string, FSWatcher>();
|
||||
const debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
||||
const fileExists = fsDeps?.existsSync ?? existsSync;
|
||||
const watchFs = fsDeps?.watch ?? watch;
|
||||
|
||||
function watchPlugin(pluginId: string, packagePath: string): void {
|
||||
// Don't double-watch
|
||||
@@ -169,60 +188,70 @@ export function createPluginDevWatcher(
|
||||
return;
|
||||
}
|
||||
|
||||
const activeWatchers = watcherTargets.map((target) => {
|
||||
const watcher = watchFs(target.path, { recursive: target.recursive }, (_event, filename) => {
|
||||
if (shouldIgnorePath(filename)) return;
|
||||
const watcher = chokidar.watch(
|
||||
watcherTargets.map((target) => target.path),
|
||||
{
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 200,
|
||||
pollInterval: 100,
|
||||
},
|
||||
ignored: (watchedPath) => {
|
||||
const relativePath = path.relative(absPath, watchedPath);
|
||||
return shouldIgnorePath(relativePath);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// Debounce: multiple rapid file changes collapse into one restart
|
||||
const existing = debounceTimers.get(pluginId);
|
||||
if (existing) clearTimeout(existing);
|
||||
watcher.on("all", (_eventName, changedPath) => {
|
||||
const relativePath = path.relative(absPath, changedPath);
|
||||
if (shouldIgnorePath(relativePath)) return;
|
||||
|
||||
debounceTimers.set(
|
||||
pluginId,
|
||||
setTimeout(() => {
|
||||
debounceTimers.delete(pluginId);
|
||||
log.info(
|
||||
{ pluginId, changedFile: filename, watchTarget: target.path },
|
||||
"plugin-dev-watcher: file change detected, restarting worker",
|
||||
const existing = debounceTimers.get(pluginId);
|
||||
if (existing) clearTimeout(existing);
|
||||
|
||||
debounceTimers.set(
|
||||
pluginId,
|
||||
setTimeout(() => {
|
||||
debounceTimers.delete(pluginId);
|
||||
log.info(
|
||||
{ pluginId, changedFile: relativePath || path.basename(changedPath) },
|
||||
"plugin-dev-watcher: file change detected, restarting worker",
|
||||
);
|
||||
|
||||
lifecycle.restartWorker(pluginId).catch((err) => {
|
||||
log.warn(
|
||||
{
|
||||
pluginId,
|
||||
err: err instanceof Error ? err.message : String(err),
|
||||
},
|
||||
"plugin-dev-watcher: failed to restart worker after file change",
|
||||
);
|
||||
|
||||
lifecycle.restartWorker(pluginId).catch((err) => {
|
||||
log.warn(
|
||||
{
|
||||
pluginId,
|
||||
err: err instanceof Error ? err.message : String(err),
|
||||
},
|
||||
"plugin-dev-watcher: failed to restart worker after file change",
|
||||
);
|
||||
});
|
||||
}, DEBOUNCE_MS),
|
||||
);
|
||||
});
|
||||
|
||||
watcher.on("error", (err) => {
|
||||
log.warn(
|
||||
{
|
||||
pluginId,
|
||||
packagePath: absPath,
|
||||
watchTarget: target.path,
|
||||
err: err instanceof Error ? err.message : String(err),
|
||||
},
|
||||
"plugin-dev-watcher: watcher error, stopping watch for this plugin",
|
||||
);
|
||||
unwatchPlugin(pluginId);
|
||||
});
|
||||
|
||||
return watcher;
|
||||
});
|
||||
}, DEBOUNCE_MS),
|
||||
);
|
||||
});
|
||||
|
||||
watchers.set(pluginId, activeWatchers);
|
||||
watcher.on("error", (err) => {
|
||||
log.warn(
|
||||
{
|
||||
pluginId,
|
||||
packagePath: absPath,
|
||||
err: err instanceof Error ? err.message : String(err),
|
||||
},
|
||||
"plugin-dev-watcher: watcher error, stopping watch for this plugin",
|
||||
);
|
||||
unwatchPlugin(pluginId);
|
||||
});
|
||||
|
||||
watchers.set(pluginId, watcher);
|
||||
log.info(
|
||||
{
|
||||
pluginId,
|
||||
packagePath: absPath,
|
||||
watchTargets: watcherTargets.map((target) => ({
|
||||
path: target.path,
|
||||
recursive: target.recursive,
|
||||
kind: target.kind,
|
||||
})),
|
||||
},
|
||||
"plugin-dev-watcher: watching local plugin for changes",
|
||||
@@ -240,11 +269,9 @@ export function createPluginDevWatcher(
|
||||
}
|
||||
|
||||
function unwatchPlugin(pluginId: string): void {
|
||||
const pluginWatchers = watchers.get(pluginId);
|
||||
if (pluginWatchers) {
|
||||
for (const watcher of pluginWatchers) {
|
||||
watcher.close();
|
||||
}
|
||||
const pluginWatcher = watchers.get(pluginId);
|
||||
if (pluginWatcher) {
|
||||
void pluginWatcher.close();
|
||||
watchers.delete(pluginId);
|
||||
}
|
||||
const timer = debounceTimers.get(pluginId);
|
||||
|
||||
Reference in New Issue
Block a user