termcast 1.3.33 → 1.3.35
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.
- package/dist/apis/cache.d.ts +1 -2
- package/dist/apis/cache.d.ts.map +1 -1
- package/dist/apis/cache.js +134 -52
- package/dist/apis/cache.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +25 -0
- package/dist/build.js.map +1 -1
- package/dist/cli.js +6 -8
- package/dist/cli.js.map +1 -1
- package/dist/components/dropdown.js +3 -3
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/footer.d.ts.map +1 -1
- package/dist/components/footer.js +1 -1
- package/dist/components/footer.js.map +1 -1
- package/dist/components/icon.d.ts.map +1 -1
- package/dist/components/icon.js +386 -23
- package/dist/components/icon.js.map +1 -1
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +90 -22
- package/dist/components/list.js.map +1 -1
- package/dist/examples/list-controlled-search.d.ts +2 -0
- package/dist/examples/list-controlled-search.d.ts.map +1 -0
- package/dist/examples/list-controlled-search.js +12 -0
- package/dist/examples/list-controlled-search.js.map +1 -0
- package/dist/extensions/home.js +1 -1
- package/dist/extensions/home.js.map +1 -1
- package/dist/extensions/react-refresh-init.d.ts.map +1 -1
- package/dist/extensions/react-refresh-init.js +4 -3
- package/dist/extensions/react-refresh-init.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/dialog.d.ts.map +1 -1
- package/dist/internal/dialog.js +4 -5
- package/dist/internal/dialog.js.map +1 -1
- package/dist/internal/providers.d.ts.map +1 -1
- package/dist/internal/providers.js +18 -5
- package/dist/internal/providers.js.map +1 -1
- package/dist/state.d.ts +1 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js.map +1 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +6 -2
- package/dist/theme.js.map +1 -1
- package/dist/utils/run-command.js +3 -3
- package/dist/utils/run-command.js.map +1 -1
- package/dist/utils.d.ts +16 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +28 -1
- package/dist/utils.js.map +1 -1
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +24 -4
- package/dist/watcher.js.map +1 -1
- package/package.json +10 -9
- package/src/apis/cache.test.ts +35 -3
- package/src/apis/cache.tsx +180 -57
- package/src/build.tsx +28 -0
- package/src/cli.tsx +8 -10
- package/src/compile.vitest.tsx +42 -24
- package/src/components/dropdown.tsx +3 -3
- package/src/components/footer.tsx +4 -2
- package/src/components/icon.tsx +385 -23
- package/src/components/list.tsx +104 -28
- package/src/examples/github.vitest.tsx +37 -37
- package/src/examples/list-controlled-search.tsx +28 -0
- package/src/examples/list-controlled-search.vitest.tsx +49 -0
- package/src/examples/list-detail-metadata.vitest.tsx +1 -1
- package/src/examples/list-dropdown-default.vitest.tsx +9 -9
- package/src/examples/list-scrollbox.vitest.tsx +55 -41
- package/src/examples/list-with-detail.vitest.tsx +35 -36
- package/src/examples/list-with-dropdown.vitest.tsx +2 -2
- package/src/examples/list-with-sections.vitest.tsx +153 -118
- package/src/examples/simple-file-picker.vitest.tsx +1 -1
- package/src/examples/simple-grid.vitest.tsx +44 -44
- package/src/examples/simple-navigation.vitest.tsx +43 -12
- package/src/examples/store.vitest.tsx +1 -1
- package/src/examples/swift-extension.vitest.tsx +3 -3
- package/src/extensions/dev.vitest.tsx +69 -34
- package/src/extensions/home.tsx +1 -1
- package/src/extensions/react-refresh-init.tsx +4 -3
- package/src/index.tsx +1 -0
- package/src/internal/dialog.tsx +21 -23
- package/src/internal/providers.tsx +18 -5
- package/src/state.tsx +1 -0
- package/src/theme.tsx +6 -2
- package/src/utils/run-command.tsx +3 -3
- package/src/utils.tsx +41 -1
- package/src/watcher.tsx +26 -6
package/src/internal/dialog.tsx
CHANGED
|
@@ -151,7 +151,6 @@ export function DialogOverlay(): any {
|
|
|
151
151
|
const dialogStack = useStore((state) => state.dialogStack)
|
|
152
152
|
const showActionsDialog = useStore((state) => state.showActionsDialog)
|
|
153
153
|
const navContext = useContext(NavigationContext)
|
|
154
|
-
const theme = useTheme()
|
|
155
154
|
|
|
156
155
|
const setActionsPortalTargetRef = useCallback((node: any) => {
|
|
157
156
|
if (!node) {
|
|
@@ -177,13 +176,33 @@ export function DialogOverlay(): any {
|
|
|
177
176
|
|
|
178
177
|
return (
|
|
179
178
|
<>
|
|
179
|
+
{item && (
|
|
180
|
+
<box position='absolute' width='100%' height='100%' flexDirection='column'>
|
|
181
|
+
<InFocus inFocus={true}>
|
|
182
|
+
<Dialog
|
|
183
|
+
position={item.position}
|
|
184
|
+
onClickOutside={() => {
|
|
185
|
+
const state = useStore.getState()
|
|
186
|
+
if (state.dialogStack.length > 0) {
|
|
187
|
+
useStore.setState({
|
|
188
|
+
dialogStack: state.dialogStack.slice(0, -1),
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
}}
|
|
192
|
+
>
|
|
193
|
+
<NavigationContext.Provider value={navContext}>
|
|
194
|
+
{item.element}
|
|
195
|
+
</NavigationContext.Provider>
|
|
196
|
+
</Dialog>
|
|
197
|
+
</InFocus>
|
|
198
|
+
</box>
|
|
199
|
+
)}
|
|
180
200
|
{showActionsDialog && (
|
|
181
201
|
<box
|
|
182
202
|
position='absolute'
|
|
183
203
|
width='100%'
|
|
184
204
|
height='100%'
|
|
185
205
|
flexDirection='column'
|
|
186
|
-
backgroundColor={theme.background}
|
|
187
206
|
>
|
|
188
207
|
<InFocus inFocus={true}>
|
|
189
208
|
<Dialog
|
|
@@ -201,27 +220,6 @@ export function DialogOverlay(): any {
|
|
|
201
220
|
</InFocus>
|
|
202
221
|
</box>
|
|
203
222
|
)}
|
|
204
|
-
{item && (
|
|
205
|
-
<box position='absolute' width='100%' height='100%' flexDirection='column'>
|
|
206
|
-
<InFocus inFocus={true}>
|
|
207
|
-
<Dialog
|
|
208
|
-
position={item.position}
|
|
209
|
-
onClickOutside={() => {
|
|
210
|
-
const state = useStore.getState()
|
|
211
|
-
if (state.dialogStack.length > 0) {
|
|
212
|
-
useStore.setState({
|
|
213
|
-
dialogStack: state.dialogStack.slice(0, -1),
|
|
214
|
-
})
|
|
215
|
-
}
|
|
216
|
-
}}
|
|
217
|
-
>
|
|
218
|
-
<NavigationContext.Provider value={navContext}>
|
|
219
|
-
{item.element}
|
|
220
|
-
</NavigationContext.Provider>
|
|
221
|
-
</Dialog>
|
|
222
|
-
</InFocus>
|
|
223
|
-
</box>
|
|
224
|
-
)}
|
|
225
223
|
</>
|
|
226
224
|
)
|
|
227
225
|
}
|
|
@@ -35,20 +35,33 @@ const queryClient = new QueryClient({
|
|
|
35
35
|
},
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
//
|
|
39
|
-
|
|
38
|
+
// Lazy-initialized Cache for TanStack Query persistence.
|
|
39
|
+
// Must not be created at module load time because extensionPath may not be set yet
|
|
40
|
+
// (e.g. when renderWithProviders sets state right before rendering).
|
|
41
|
+
// Tracks the extensionPath it was created with so it can be recreated if the path changes.
|
|
42
|
+
let queryCache: Cache | null = null
|
|
43
|
+
let queryCachePath: string | null = null
|
|
44
|
+
|
|
45
|
+
function getQueryCache(): Cache {
|
|
46
|
+
const currentPath = useStore.getState().extensionPath
|
|
47
|
+
if (!queryCache || currentPath !== queryCachePath) {
|
|
48
|
+
queryCache = new Cache({ namespace: 'tanstack-query' })
|
|
49
|
+
queryCachePath = currentPath
|
|
50
|
+
}
|
|
51
|
+
return queryCache
|
|
52
|
+
}
|
|
40
53
|
|
|
41
54
|
const persister = {
|
|
42
55
|
persistClient: async (client: any) => {
|
|
43
56
|
const serialized = JSON.stringify(client)
|
|
44
|
-
|
|
57
|
+
getQueryCache().set('query-client-data', serialized)
|
|
45
58
|
},
|
|
46
59
|
restoreClient: async () => {
|
|
47
|
-
const data =
|
|
60
|
+
const data = getQueryCache().get('query-client-data')
|
|
48
61
|
return data ? JSON.parse(data) : undefined
|
|
49
62
|
},
|
|
50
63
|
removeClient: async () => {
|
|
51
|
-
|
|
64
|
+
getQueryCache().remove('query-client-data')
|
|
52
65
|
},
|
|
53
66
|
}
|
|
54
67
|
|
package/src/state.tsx
CHANGED
package/src/theme.tsx
CHANGED
|
@@ -3,12 +3,16 @@ import { getResolvedTheme, type ResolvedTheme, defaultThemeName, themeNames } fr
|
|
|
3
3
|
import { useStore } from './state'
|
|
4
4
|
import { Cache } from './apis/cache'
|
|
5
5
|
|
|
6
|
-
// Global cache for theme persistence (no namespace = global storage)
|
|
6
|
+
// Global cache for theme persistence (no namespace = global storage).
|
|
7
|
+
// Tracks extensionPath so the cache is recreated if the path changes.
|
|
7
8
|
let globalCache: Cache | null = null
|
|
9
|
+
let globalCachePath: string | null = null
|
|
8
10
|
|
|
9
11
|
function getGlobalCache(): Cache {
|
|
10
|
-
|
|
12
|
+
const currentPath = useStore.getState().extensionPath
|
|
13
|
+
if (!globalCache || currentPath !== globalCachePath) {
|
|
11
14
|
globalCache = new Cache()
|
|
15
|
+
globalCachePath = currentPath
|
|
12
16
|
}
|
|
13
17
|
return globalCache
|
|
14
18
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { goke } from 'goke'
|
|
3
3
|
import { useStore } from 'termcast/src/state'
|
|
4
4
|
import { showToast, Toast } from 'termcast/src/apis/toast'
|
|
5
5
|
import { LocalStorage } from 'termcast/src/apis/localstorage'
|
|
@@ -31,13 +31,13 @@ export interface ParsedExtensionArgs {
|
|
|
31
31
|
export function parseExtensionArgs({
|
|
32
32
|
skipArgv = 0,
|
|
33
33
|
}: { skipArgv?: number } = {}): ParsedExtensionArgs {
|
|
34
|
-
// Build argv for
|
|
34
|
+
// Build argv for goke: keep first 2 (binary + script), skip subcommand args, keep the rest
|
|
35
35
|
const argv = [
|
|
36
36
|
process.argv[0],
|
|
37
37
|
process.argv[1],
|
|
38
38
|
...process.argv.slice(2 + skipArgv),
|
|
39
39
|
]
|
|
40
|
-
const parsed =
|
|
40
|
+
const parsed = goke().parse(argv, { run: false })
|
|
41
41
|
return {
|
|
42
42
|
commandName: parsed.args[0] as string | undefined,
|
|
43
43
|
showHelp: Boolean(parsed.options.help || parsed.options.h),
|
package/src/utils.tsx
CHANGED
|
@@ -12,13 +12,53 @@ import {
|
|
|
12
12
|
type CommandWithFile,
|
|
13
13
|
} from './package-json'
|
|
14
14
|
import { logger } from './logger'
|
|
15
|
+
import { useStore } from './state'
|
|
16
|
+
|
|
17
|
+
export interface RenderWithProvidersOptions {
|
|
18
|
+
extensionName?: string
|
|
19
|
+
extensionPath?: string
|
|
20
|
+
packageJson?: RaycastPackageJson
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Render a React element wrapped in TermcastProvider with all necessary state initialized.
|
|
25
|
+
*
|
|
26
|
+
* Sets up extensionPath (for LocalStorage, Cache, assets) and extensionPackageJson
|
|
27
|
+
* (for preferences, environment metadata, action panel config) before rendering.
|
|
28
|
+
*
|
|
29
|
+
* - extensionName defaults to 'termcast-app'
|
|
30
|
+
* - extensionPath defaults to ~/.termcast/compiled/{extensionName}
|
|
31
|
+
* - packageJson defaults to a minimal { name, title, commands: [] }
|
|
32
|
+
*/
|
|
33
|
+
export async function renderWithProviders(
|
|
34
|
+
element: ReactNode,
|
|
35
|
+
options?: RenderWithProvidersOptions,
|
|
36
|
+
): Promise<void> {
|
|
37
|
+
const extensionName = options?.extensionName || 'termcast-app'
|
|
38
|
+
const extensionPath =
|
|
39
|
+
options?.extensionPath ||
|
|
40
|
+
path.join(os.homedir(), '.termcast', 'compiled', extensionName)
|
|
41
|
+
const packageJson: RaycastPackageJson = options?.packageJson || {
|
|
42
|
+
name: extensionName,
|
|
43
|
+
title: extensionName,
|
|
44
|
+
description: '',
|
|
45
|
+
commands: [],
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Reset store to initial state then set extension fields, matching
|
|
49
|
+
// startDevMode/startCompiledExtension behavior to avoid stale navigation/dialog state
|
|
50
|
+
useStore.setState({
|
|
51
|
+
...useStore.getInitialState(),
|
|
52
|
+
extensionPath,
|
|
53
|
+
extensionPackageJson: packageJson,
|
|
54
|
+
})
|
|
15
55
|
|
|
16
|
-
export async function renderWithProviders(element: ReactNode): Promise<void> {
|
|
17
56
|
const renderer = await createCliRenderer({
|
|
18
57
|
onDestroy: () => {
|
|
19
58
|
process.exit(0)
|
|
20
59
|
},
|
|
21
60
|
})
|
|
61
|
+
|
|
22
62
|
createRoot(renderer).render(<TermcastProvider>{element}</TermcastProvider>)
|
|
23
63
|
}
|
|
24
64
|
|
package/src/watcher.tsx
CHANGED
|
@@ -6,14 +6,34 @@ import type ParcelWatcher from '@parcel/watcher'
|
|
|
6
6
|
|
|
7
7
|
let _watcher: typeof ParcelWatcher | undefined
|
|
8
8
|
|
|
9
|
+
function getWatcherPackageName(): string {
|
|
10
|
+
const suffix = process.platform === 'linux' ? '-glibc' : ''
|
|
11
|
+
return `@parcel/watcher-${process.platform}-${process.arch}${suffix}`
|
|
12
|
+
}
|
|
13
|
+
|
|
9
14
|
export function getWatcher(): typeof ParcelWatcher {
|
|
10
15
|
if (_watcher) return _watcher
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
16
|
+
const watcherPackageName = getWatcherPackageName()
|
|
17
|
+
let binding: unknown
|
|
18
|
+
try {
|
|
19
|
+
// Use require with template literal so Bun can analyze and bundle the native module
|
|
20
|
+
binding = require(watcherPackageName)
|
|
21
|
+
} catch (error) {
|
|
22
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
23
|
+
throw new Error(
|
|
24
|
+
[
|
|
25
|
+
`Failed to load native watcher package \"${watcherPackageName}\".`,
|
|
26
|
+
`Current platform: ${process.platform}-${process.arch}.`,
|
|
27
|
+
'',
|
|
28
|
+
'This usually means Bun blocked install scripts for watcher packages.',
|
|
29
|
+
'Fix with:',
|
|
30
|
+
' bun pm trust @parcel/watcher',
|
|
31
|
+
' bun install',
|
|
32
|
+
'',
|
|
33
|
+
`Original error: ${message}`,
|
|
34
|
+
].join('\n'),
|
|
35
|
+
)
|
|
36
|
+
}
|
|
17
37
|
_watcher = createWrapper(binding)
|
|
18
38
|
return _watcher!
|
|
19
39
|
}
|