@stacksjs/desktop 0.2.112 → 0.2.114

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.
@@ -0,0 +1,23 @@
1
+ export type { PackageConfig, PackageResult } from 'craft-native';
2
+ /**
3
+ * Packaging and code signing.
4
+ *
5
+ * Craft owns the native side of this — building the `.app`, the DMG, the MSI,
6
+ * the Linux packages, and the signed `.pkg` the Mac App Store accepts. This
7
+ * module re-exports it so an app reaches packaging through the same import as
8
+ * the rest of the desktop API, rather than depending on Craft directly.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { packageApp } from '@stacksjs/stx/desktop'
13
+ *
14
+ * await packageApp({
15
+ * name: 'Barista',
16
+ * version: '0.1.0',
17
+ * binaryPath: './dist/barista',
18
+ * bundleId: 'org.stacksjs.barista',
19
+ * macos: { menuBarOnly: true, dmg: true },
20
+ * })
21
+ * ```
22
+ */
23
+ export { pack, packageApp } from 'craft-native';
@@ -1,4 +1,49 @@
1
1
  // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ if (canCache)
29
+ cache.set(mod, to);
30
+ return to;
31
+ };
32
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __returnValue = (v) => v;
34
+ function __exportSetter(name, newValue) {
35
+ this[name] = __returnValue.bind(null, newValue);
36
+ }
37
+ var __export = (target, all) => {
38
+ for (var name in all)
39
+ __defProp(target, name, {
40
+ get: all[name],
41
+ enumerable: true,
42
+ configurable: true,
43
+ set: __exportSetter.bind(all, name)
44
+ });
45
+ };
46
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
2
47
  var __require = import.meta.require;
3
48
 
4
49
  // src/test-utils.ts
@@ -105,4 +150,4 @@ export {
105
150
  findCall
106
151
  };
107
152
 
108
- //# debugId=112673127C3680E664756E2164756E21
153
+ //# debugId=A2381B1EFA0ECC1764756E2164756E21
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "/**\n * Test utilities — install a mock `window.craft` namespace + capture\n * every call against it. Apps consuming this package can `import {\n * installMockBridge } from '@stacksjs/desktop/test-utils'` to hand\n * their unit tests the same harness this package uses internally.\n *\n * The mock auto-vivifies namespaces on access — `craft.fs.readFile`\n * works without pre-declaring `fs`. Methods return a Promise resolving\n * to whatever was queued via `whenCalled`, defaulting to `undefined`.\n *\n * Tests should follow the install / call / assert / uninstall cycle:\n * ```ts\n * import { installMockBridge, findCall } from '@stacksjs/desktop/test-utils'\n * import { fs } from '@stacksjs/desktop'\n *\n * const bridge = installMockBridge()\n * bridge.whenCalled('fs', 'readFile', { data: 'hello' })\n * expect(await fs.readFile('/x')).toBe('hello')\n * expect(findCall(bridge.calls, 'fs', 'readFile')!.args).toEqual(['/x'])\n * bridge.uninstall()\n * ```\n *\n * Polyfills `window.addEventListener` / `dispatchEvent` for runners\n * (very-happy-dom, jsdom older versions) that don't ship them by\n * default — facade tests rely on those for event-based facades.\n */\n\nensureWindowEventTarget()\n\nfunction ensureWindowEventTarget(): void {\n if (typeof window === 'undefined') return\n const w = window as any\n if (typeof w.addEventListener === 'function' && typeof w.dispatchEvent === 'function') return\n\n const listeners = new Map<string, Set<EventListener>>()\n\n w.addEventListener = (name: string, cb: EventListener): void => {\n let set = listeners.get(name)\n if (!set) {\n set = new Set()\n listeners.set(name, set)\n }\n set.add(cb)\n }\n\n w.removeEventListener = (name: string, cb: EventListener): void => {\n listeners.get(name)?.delete(cb)\n }\n\n w.dispatchEvent = (event: Event): boolean => {\n const set = listeners.get(event.type)\n if (set) {\n for (const fn of set) {\n try { fn(event) } catch { /* swallow listener errors during tests */ }\n }\n }\n return true\n }\n}\n\nexport interface CapturedCall {\n ns: string\n method: string\n args: unknown[]\n}\n\nexport interface MockBridgeHandle {\n /** Calls captured since the bridge was installed. */\n calls: CapturedCall[]\n /**\n * Queue the response from `window.craft[ns][method]`. The mock\n * walks: explicit return → matched response handler → default.\n */\n whenCalled: (\n ns: string,\n method: string,\n response: unknown | ((...args: unknown[]) => unknown)\n ) => void\n /** Remove the mock and restore whatever was on window.craft before. */\n uninstall: () => void\n}\n\nexport function installMockBridge(initialNamespaces: string[] = []): MockBridgeHandle {\n const calls: CapturedCall[] = []\n const responses = new Map<string, unknown | ((...args: unknown[]) => unknown)>()\n\n // If the production bridge IIFE has already loaded — flagged via\n // `__craft_bridge_loaded` — treat the existing window.craft as\n // \"no real previous.\" Otherwise restoring it on uninstall would\n // leak the production facade into \"no bridge\" assertions in\n // subsequent tests.\n const previousRaw = (window as any).craft\n const previous = previousRaw && previousRaw.__craft_bridge_loaded ? undefined : previousRaw\n\n function makeMethod(ns: string, method: string) {\n return (...args: unknown[]) => {\n calls.push({ ns, method, args })\n const key = `${ns}:${method}`\n if (responses.has(key)) {\n const r = responses.get(key)\n const resolved = typeof r === 'function'\n ? (r as (...a: unknown[]) => unknown)(...args)\n : r\n return Promise.resolve(resolved)\n }\n return Promise.resolve(undefined)\n }\n }\n\n function makeNamespace(ns: string): Record<string, unknown> {\n return new Proxy({} as Record<string, unknown>, {\n get(_target, prop: string) {\n if (typeof prop !== 'string') return undefined\n // Some non-method properties may be read synchronously (e.g.\n // theme.get returns an object, not a promise). Allow callers\n // to register those by passing a zero-arg function — we\n // recognize the shape and return the value synchronously.\n if (responses.has(`${ns}:${prop}`)) {\n const r = responses.get(`${ns}:${prop}`)\n if (typeof r === 'function' && r.length === 0) {\n return () => {\n calls.push({ ns, method: prop, args: [] })\n return (r as () => unknown)()\n }\n }\n }\n return makeMethod(ns, prop)\n },\n })\n }\n\n const root = new Proxy({} as Record<string, unknown>, {\n get(_target, prop: string) {\n if (typeof prop !== 'string') return undefined\n return makeNamespace(prop)\n },\n has(_target, prop) {\n if (typeof prop !== 'string') return false\n if (initialNamespaces.length === 0) return true\n return initialNamespaces.includes(prop)\n },\n })\n\n ;(window as any).craft = root\n\n return {\n calls,\n whenCalled(ns, method, response) {\n responses.set(`${ns}:${method}`, response)\n },\n uninstall() {\n if (previous === undefined) {\n delete (window as any).craft\n }\n else {\n ;(window as any).craft = previous\n }\n },\n }\n}\n\n/** Helper — find the first captured call matching `ns` + `method`. */\nexport function findCall(\n calls: CapturedCall[],\n ns: string,\n method: string,\n): CapturedCall | undefined {\n return calls.find(c => c.ns === ns && c.method === method)\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "112673127C3680E664756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "A2381B1EFA0ECC1764756E2164756E21",
9
9
  "names": []
10
10
  }
package/dist/types.d.ts CHANGED
@@ -58,6 +58,9 @@ export declare interface WindowOptions {
58
58
  frameless?: boolean
59
59
  titlebarHidden?: boolean
60
60
  backgroundColor?: string
61
+ systemTray?: boolean
62
+ hideDockIcon?: boolean
63
+ devTools?: boolean
61
64
  nativeSidebar?: boolean
62
65
  sidebarWidth?: number
63
66
  sidebarConfig?: SidebarConfig
package/dist/window.d.ts CHANGED
@@ -32,11 +32,19 @@ export declare function getWindow(id: string): WindowInstance | null;
32
32
  * Close all active windows
33
33
  */
34
34
  export declare function closeAllWindows(): void;
35
+ /**
36
+ * Translate window options into Craft binary arguments.
37
+ *
38
+ * craft-native is a thin wrapper around this command line, so the same options
39
+ * describe a window whether the JS package is installed or not.
40
+ */
41
+ export declare function craftWindowArguments(url: string, options?: WindowOptions): string[];
35
42
  /**
36
43
  * Create a native window with URL
37
44
  *
38
- * Uses ts-craft to create native desktop windows. Falls back to returning null
39
- * if ts-craft is not available.
45
+ * Prefers the craft-native package for its richer typings, and falls back to
46
+ * spawning the Craft binary directly when it isn't installed — the binary is
47
+ * what craft-native drives anyway, so an app needs only one of the two.
40
48
  *
41
49
  * ## Window Control
42
50
  *
@@ -57,20 +65,20 @@ export declare function closeAllWindows(): void;
57
65
  *
58
66
  * @param url - URL to load in the window
59
67
  * @param options - Window configuration options
60
- * @returns WindowInstance if successful, null if ts-craft unavailable
68
+ * @returns WindowInstance if successful, null if no Craft runtime is available
61
69
  */
62
70
  export declare function createWindow(url: string, options?: WindowOptions): Promise<WindowInstance | null>;
63
71
  /**
64
72
  * Open a development server window
65
73
  * This is specifically for the stx dev server --native flag
66
74
  *
67
- * Uses ts-craft to create a native window, falls back to browser if unavailable.
75
+ * Uses craft-native to create a native window, falls back to browser if unavailable.
68
76
  */
69
77
  export declare function openDevWindow(port: number, options?: WindowOptions): Promise<boolean>;
70
78
  /**
71
79
  * Create a window with HTML content
72
80
  *
73
- * Uses ts-craft to display HTML content in a native window.
81
+ * Uses craft-native to display HTML content in a native window.
74
82
  */
75
83
  export declare function createWindowWithHTML(html: string, options?: WindowOptions): Promise<WindowInstance | null>;
76
84
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/desktop",
3
3
  "type": "module",
4
- "version": "0.2.112",
4
+ "version": "0.2.114",
5
5
  "description": "Native desktop application framework for stx (powered by Craft)",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -54,12 +54,7 @@
54
54
  "test:coverage": "bun test --coverage --preload ../../test-utils/happy-dom.ts",
55
55
  "typecheck": "bun tsc --noEmit"
56
56
  },
57
- "peerDependencies": {
58
- "craft": "*"
59
- },
60
- "peerDependenciesMeta": {
61
- "craft": {
62
- "optional": true
63
- }
57
+ "dependencies": {
58
+ "craft-native": ">=0.0.37"
64
59
  }
65
60
  }