@owdproject/core 3.4.0 → 4.0.0-alpha.3

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 (108) hide show
  1. package/README.md +112 -13
  2. package/dist/dom/index.d.mts +65 -0
  3. package/dist/dom/index.d.ts +65 -0
  4. package/dist/dom/index.mjs +224 -0
  5. package/dist/events/index.d.mts +70 -0
  6. package/dist/events/index.d.ts +70 -0
  7. package/dist/events/index.mjs +3 -0
  8. package/dist/index.d.mts +73 -0
  9. package/dist/index.d.ts +73 -0
  10. package/dist/index.mjs +115 -0
  11. package/dist/layout/index.d.mts +41 -0
  12. package/dist/layout/index.d.ts +41 -0
  13. package/dist/layout/index.mjs +64 -0
  14. package/dist/machines/index.d.mts +31 -0
  15. package/dist/machines/index.d.ts +31 -0
  16. package/dist/machines/index.mjs +2 -0
  17. package/dist/managers/index.d.mts +117 -0
  18. package/dist/managers/index.d.ts +117 -0
  19. package/dist/managers/index.mjs +6 -0
  20. package/dist/session/index.d.mts +57 -0
  21. package/dist/session/index.d.ts +57 -0
  22. package/dist/session/index.mjs +65 -0
  23. package/dist/shared/core.B0B0KfVK.mjs +865 -0
  24. package/dist/shared/core.B1XxB289.mjs +239 -0
  25. package/dist/shared/core.B3mp7ztE.mjs +237 -0
  26. package/dist/shared/core.BOvFdEVQ.d.ts +114 -0
  27. package/dist/shared/core.CsDFgGnX.mjs +40 -0
  28. package/dist/shared/core.Di1eFcr_.d.mts +114 -0
  29. package/dist/shared/core.Pd_Ogt4g.mjs +101 -0
  30. package/dist/shared/core.b3Xldzyu.mjs +29 -0
  31. package/dist/types/index.d.mts +266 -0
  32. package/dist/types/index.d.ts +266 -0
  33. package/dist/types/index.mjs +1 -0
  34. package/package.json +56 -112
  35. package/CHANGELOG.md +0 -98
  36. package/DESKTOP_KERNEL.md +0 -232
  37. package/MIGRATION_3.3.2.md +0 -23
  38. package/MIGRATION_3.4.md +0 -126
  39. package/PLAYGROUND.md +0 -91
  40. package/dist/module.d.mts +0 -13
  41. package/dist/module.json +0 -9
  42. package/dist/module.mjs +0 -254
  43. package/dist/types.d.mts +0 -7
  44. package/index.ts +0 -8
  45. package/kit/authoring.ts +0 -340
  46. package/kit/defineDesktopApp.ts +0 -56
  47. package/module.ts +0 -203
  48. package/runtime/components/Application/DesktopCoreApplicationRender.vue +0 -20
  49. package/runtime/components/Application/DesktopCoreApplicationWindowsRender.vue +0 -38
  50. package/runtime/components/background/DesktopCoreBackground.vue +0 -16
  51. package/runtime/components/core/DesktopCore.vue +0 -43
  52. package/runtime/components/time/DesktopCoreTime.vue +0 -56
  53. package/runtime/components/window/DesktopCoreWindow.vue +0 -215
  54. package/runtime/components/window/DesktopCoreWindowContent.vue +0 -28
  55. package/runtime/components/window/DesktopCoreWindowNav.vue +0 -66
  56. package/runtime/components/window/DesktopCoreWindowSnapHintsBase.vue +0 -74
  57. package/runtime/components/workspace/DesktopCoreWorkspaceEdgeHintsBase.vue +0 -84
  58. package/runtime/composables/useApplicationEntries.ts +0 -51
  59. package/runtime/composables/useApplicationManager.ts +0 -285
  60. package/runtime/composables/useBlockNonInputContextMenu.ts +0 -30
  61. package/runtime/composables/useDesktopConfig.ts +0 -8
  62. package/runtime/composables/useDesktopDialogs.ts +0 -16
  63. package/runtime/composables/useDesktopExtension.ts +0 -8
  64. package/runtime/composables/useDesktopManager.ts +0 -51
  65. package/runtime/composables/useDesktopManifest.ts +0 -17
  66. package/runtime/composables/useDesktopSession.ts +0 -27
  67. package/runtime/composables/useDesktopShellIdentity.ts +0 -99
  68. package/runtime/composables/useDesktopShellOptions.ts +0 -36
  69. package/runtime/composables/useDesktopShellReady.ts +0 -7
  70. package/runtime/composables/useDesktopWorkArea.ts +0 -93
  71. package/runtime/composables/useTerminalManager.ts +0 -159
  72. package/runtime/composables/useToggleWindowMaximize.ts +0 -35
  73. package/runtime/composables/useWindowDragHandlers.ts +0 -47
  74. package/runtime/composables/useWindowSnapDrop.ts +0 -112
  75. package/runtime/composables/useWorkspaceEdgeDrop.ts +0 -176
  76. package/runtime/composables/useWorkspaceManager.ts +0 -67
  77. package/runtime/composables/useWorkspaceOverviewCapture.ts +0 -92
  78. package/runtime/composables/useWorkspaceOverviewLiveScale.ts +0 -151
  79. package/runtime/constants/desktopShellKeys.ts +0 -12
  80. package/runtime/constants/shellLayout.ts +0 -5
  81. package/runtime/dialogs/desktopDialogProvider.ts +0 -73
  82. package/runtime/internal/controllers/ApplicationController.ts +0 -351
  83. package/runtime/internal/controllers/WindowController.ts +0 -547
  84. package/runtime/plugins/01.desktop-shell-init.client.ts +0 -28
  85. package/runtime/plugins/02.desktop-register-desktop-apps.client.ts +0 -13
  86. package/runtime/plugins/resize.client.ts +0 -6
  87. package/runtime/stores/storeApplicationMeta.ts +0 -60
  88. package/runtime/stores/storeApplicationWindows.ts +0 -21
  89. package/runtime/stores/storeDesktop.ts +0 -71
  90. package/runtime/stores/storeDesktopDefaultApps.ts +0 -54
  91. package/runtime/stores/storeDesktopVolume.ts +0 -19
  92. package/runtime/stores/storeDesktopWindow.ts +0 -38
  93. package/runtime/stores/storeDesktopWorkspace.ts +0 -105
  94. package/runtime/stores/storeIds.ts +0 -35
  95. package/runtime/types/desktopMenu.ts +0 -10
  96. package/runtime/utils/initDesktopShell.ts +0 -80
  97. package/runtime/utils/migratePersistedStoreIds.ts +0 -57
  98. package/runtime/utils/utilApp.ts +0 -25
  99. package/runtime/utils/utilCaptureElementToCanvas.ts +0 -21
  100. package/runtime/utils/utilCommon.ts +0 -26
  101. package/runtime/utils/utilDebug.ts +0 -30
  102. package/runtime/utils/utilDetectSnapZone.ts +0 -57
  103. package/runtime/utils/utilTerminal.ts +0 -6
  104. package/runtime/utils/utilWindowControllerAdapter.ts +0 -15
  105. package/runtime/utils/utilWindowLayout.ts +0 -82
  106. package/runtime/utils/utilWindowMaximizeLayout.ts +0 -44
  107. package/runtime/utils/utilWorkspaceWindows.ts +0 -33
  108. package/types/index.d.ts +0 -531
@@ -1,71 +0,0 @@
1
- import { defineStore } from 'pinia'
2
- import { ref } from 'vue'
3
- import { DESKTOP_STORE_ID } from './storeIds'
4
-
5
- export const useDesktopStore = defineStore(
6
- DESKTOP_STORE_ID,
7
- () => {
8
- const state = ref<{
9
- workspace: {
10
- overview: boolean
11
- active: string
12
- list: string[]
13
- }
14
- volume: {
15
- master: number
16
- }
17
- window: {
18
- positionZ: number
19
- }
20
- defaultApps: Record<string, { applicationId: string; entry: string }>
21
- personalization: {
22
- windowSurface: 'acrylic' | 'solid'
23
- windowTint: string
24
- appearance: 'dark' | 'light'
25
- }
26
- }>({
27
- workspace: {
28
- overview: false,
29
- active: '',
30
- list: [],
31
- },
32
- volume: {
33
- master: 100,
34
- },
35
- window: {
36
- positionZ: 0,
37
- },
38
- defaultApps: {},
39
- personalization: {
40
- windowSurface: 'acrylic',
41
- windowTint: '#2d2d30',
42
- appearance: 'dark',
43
- },
44
- })
45
-
46
- function setWindowSurface(value: 'acrylic' | 'solid') {
47
- state.value.personalization.windowSurface = value
48
- }
49
-
50
- function setWindowTint(value: string) {
51
- state.value.personalization.windowTint = value
52
- }
53
-
54
- function setAppearance(value: 'dark' | 'light') {
55
- state.value.personalization.appearance = value
56
- }
57
-
58
- return {
59
- state,
60
- setWindowSurface,
61
- setWindowTint,
62
- setAppearance,
63
- }
64
- },
65
- {
66
- // @ts-expect-error
67
- persistedState: {
68
- persist: true,
69
- },
70
- },
71
- )
@@ -1,54 +0,0 @@
1
- import { defineStore } from 'pinia'
2
- import { useDesktopStore } from './storeDesktop'
3
- import { DESKTOP_DEFAULT_APPS_STORE_ID } from './storeIds'
4
-
5
- export const useDesktopDefaultAppsStore = defineStore(
6
- DESKTOP_DEFAULT_APPS_STORE_ID,
7
- () => {
8
- const desktopStore = useDesktopStore()
9
-
10
- /**
11
- * Sets a default app for a given feature
12
- */
13
- function setDefaultApp(
14
- feature: string,
15
- application: IApplicationController,
16
- entry: string,
17
- ) {
18
- if (!desktopStore.state.hasOwnProperty('defaultApps')) {
19
- desktopStore.state.defaultApps = {}
20
- }
21
-
22
- desktopStore.state.defaultApps[feature] = {
23
- applicationId: application.id,
24
- entry,
25
- }
26
- }
27
-
28
- /**
29
- * Gets the default app config for a given feature
30
- */
31
- function getDefaultApp(feature: string): DefaultAppConfig | undefined {
32
- if (!desktopStore.state.hasOwnProperty('defaultApps')) {
33
- desktopStore.state.defaultApps = {}
34
- }
35
-
36
- return desktopStore.state.defaultApps[feature]
37
- }
38
-
39
- /**
40
- * Loads default apps from current config
41
- */
42
- function loadDefaultAppsFromConfig(runtimeConfig) {
43
- if (runtimeConfig.public.desktop.defaultApps) {
44
- desktopStore.state.defaultApps = runtimeConfig.public.desktop.defaultApps
45
- }
46
- }
47
-
48
- return {
49
- setDefaultApp,
50
- getDefaultApp,
51
- loadDefaultAppsFromConfig,
52
- }
53
- },
54
- )
@@ -1,19 +0,0 @@
1
- import { defineStore } from 'pinia'
2
- import { computed } from 'vue'
3
- import { useDesktopStore } from './storeDesktop'
4
- import { DESKTOP_VOLUME_STORE_ID } from './storeIds'
5
-
6
- export const useDesktopVolumeStore = defineStore(DESKTOP_VOLUME_STORE_ID, () => {
7
- const desktopStore = useDesktopStore()
8
-
9
- const master = computed(() => desktopStore.state.volume.master)
10
-
11
- function setMasterVolume(value: number) {
12
- desktopStore.state.volume.master = value
13
- }
14
-
15
- return {
16
- master,
17
- setMasterVolume,
18
- }
19
- })
@@ -1,38 +0,0 @@
1
- import type { DesktopWorkAreaRect } from '@owdproject/core'
2
- import { defineStore } from 'pinia'
3
- import { computed, readonly, shallowRef } from 'vue'
4
- import { useDesktopStore } from './storeDesktop'
5
- import { DESKTOP_WINDOW_STORE_ID } from './storeIds'
6
-
7
- export const EMPTY_DESKTOP_WORK_AREA: DesktopWorkAreaRect = {
8
- x: 0,
9
- y: 0,
10
- width: 0,
11
- height: 0,
12
- }
13
-
14
- export const useDesktopWindowStore = defineStore(DESKTOP_WINDOW_STORE_ID, () => {
15
- const desktopStore = useDesktopStore()
16
- const workArea = shallowRef<DesktopWorkAreaRect>({
17
- ...EMPTY_DESKTOP_WORK_AREA,
18
- })
19
-
20
- const positionZ = computed(() => desktopStore.state.window.positionZ)
21
-
22
- function incrementPositionZ() {
23
- desktopStore.state.window.positionZ++
24
-
25
- return desktopStore.state.window.positionZ
26
- }
27
-
28
- function setWorkArea(rect: DesktopWorkAreaRect) {
29
- workArea.value = { ...rect }
30
- }
31
-
32
- return {
33
- positionZ,
34
- incrementPositionZ,
35
- workArea: readonly(workArea),
36
- setWorkArea,
37
- }
38
- })
@@ -1,105 +0,0 @@
1
- import { defineStore } from 'pinia'
2
- import { computed } from 'vue'
3
- import { useDesktopStore } from './storeDesktop'
4
- import { DESKTOP_WORKSPACE_STORE_ID } from './storeIds'
5
- import { nanoid } from 'nanoid'
6
-
7
- export const useDesktopWorkspaceStore = defineStore(
8
- DESKTOP_WORKSPACE_STORE_ID,
9
- () => {
10
- const desktopStore = useDesktopStore()
11
-
12
- const active = computed(() => {
13
- return desktopStore.state.workspace.active
14
- })
15
-
16
- const overview = computed(() => {
17
- return desktopStore.state.workspace.overview
18
- })
19
-
20
- const list = computed(() => {
21
- return desktopStore.state.workspace.list
22
- })
23
-
24
- function setupWorkspaces() {
25
- if (desktopStore.state.workspace.list.length === 0) {
26
- createWorkspace()
27
- }
28
-
29
- if (desktopStore.state.workspace.list.length === 1) {
30
- createWorkspace()
31
- }
32
-
33
- const list = desktopStore.state.workspace.list
34
- const active = desktopStore.state.workspace.active
35
- if (!active || !list.includes(active)) {
36
- desktopStore.state.workspace.active = list[0] ?? ''
37
- }
38
- }
39
-
40
- /** Id of the workspace new windows should use (after setupWorkspaces). */
41
- function resolveActiveWorkspaceId(): string {
42
- setupWorkspaces()
43
- return desktopStore.state.workspace.active || desktopStore.state.workspace.list[0] || ''
44
- }
45
-
46
- function setOverview(value: boolean) {
47
- desktopStore.state.workspace.overview = value
48
- }
49
-
50
- function setWorkspace(value: string) {
51
- desktopStore.state.workspace.active = value
52
- }
53
-
54
- function createWorkspace() {
55
- desktopStore.state.workspace.list.push(nanoid(8))
56
- }
57
-
58
- /** Last workspace in list excluding the given id (window migration target). */
59
- function resolveWorkspaceFallback(workspaceId: string): string | null {
60
- const remaining = desktopStore.state.workspace.list.filter(
61
- (id) => id !== workspaceId,
62
- )
63
- return remaining.at(-1) ?? null
64
- }
65
-
66
- function removeWorkspace(workspaceId: string): boolean {
67
- const list = desktopStore.state.workspace.list
68
- if (list.length <= 2) return false
69
-
70
- const index = list.indexOf(workspaceId)
71
- if (index === -1) return false
72
-
73
- const fallbackId = resolveWorkspaceFallback(workspaceId)
74
- if (!fallbackId) return false
75
-
76
- list.splice(index, 1)
77
-
78
- if (desktopStore.state.workspace.active === workspaceId) {
79
- desktopStore.state.workspace.active = fallbackId
80
- }
81
-
82
- return true
83
- }
84
-
85
- const workspaceActiveIndex = computed(() => {
86
- return desktopStore.state.workspace.list.findIndex(
87
- (workspace) => workspace === desktopStore.state.workspace.active,
88
- )
89
- })
90
-
91
- return {
92
- active,
93
- overview,
94
- list,
95
- workspaceActiveIndex,
96
- setupWorkspaces,
97
- resolveActiveWorkspaceId,
98
- setOverview,
99
- setWorkspace,
100
- createWorkspace,
101
- resolveWorkspaceFallback,
102
- removeWorkspace,
103
- }
104
- },
105
- )
@@ -1,35 +0,0 @@
1
- export const DESKTOP_STORE_ID = 'desktop'
2
- export const DESKTOP_WORKSPACE_STORE_ID = 'desktop/workspace'
3
- export const DESKTOP_WINDOW_STORE_ID = 'desktop/window'
4
- export const DESKTOP_VOLUME_STORE_ID = 'desktop/volume'
5
- export const DESKTOP_DEFAULT_APPS_STORE_ID = 'desktop/defaultApps'
6
-
7
- export const applicationWindowsStoreId = (appId: string) =>
8
- `desktop/application/${appId}/windows`
9
-
10
- export const applicationMetaStoreId = (appId: string) =>
11
- `desktop/application/${appId}/meta`
12
-
13
- export const STORE_ID_MIGRATION_FLAG = 'desktop/store-id-migration/v1'
14
-
15
- /** Static legacy Pinia store ids mapped to their 3.4 replacements. */
16
- export const LEGACY_STORE_ID_MAP: Record<string, string> = {
17
- 'owd/desktop': DESKTOP_STORE_ID,
18
- 'owd/desktop/workspace': DESKTOP_WORKSPACE_STORE_ID,
19
- 'owd/desktop/window': DESKTOP_WINDOW_STORE_ID,
20
- 'owd/desktop/volume': DESKTOP_VOLUME_STORE_ID,
21
- 'owd/desktop/defaultApps': DESKTOP_DEFAULT_APPS_STORE_ID,
22
- }
23
-
24
- export const LEGACY_APPLICATION_STORE_PATTERN =
25
- /^owd\/application\/([^/]+)\/(windows|meta)$/
26
-
27
- export function legacyApplicationStoreIdToNew(
28
- legacyId: string,
29
- ): string | null {
30
- const match = legacyId.match(LEGACY_APPLICATION_STORE_PATTERN)
31
- if (!match) return null
32
-
33
- const [, appId, kind] = match
34
- return `desktop/application/${appId}/${kind}`
35
- }
@@ -1,10 +0,0 @@
1
- /** Neutral menu model for window chrome (Menubar-compatible shape). */
2
- export interface DesktopMenuItem {
3
- label?: string
4
- icon?: string
5
- command?: () => void
6
- separator?: boolean
7
- disabled?: boolean
8
- items?: DesktopMenuItem[]
9
- [key: string]: unknown
10
- }
@@ -1,80 +0,0 @@
1
- import { setActivePinia } from 'pinia'
2
- import type { Pinia } from 'pinia'
3
- import { useAppConfig, useRuntimeConfig } from 'nuxt/app'
4
- import { toRaw } from 'vue'
5
- import { useDesktopManager } from '../composables/useDesktopManager'
6
- import { useDesktopStore } from '../stores/storeDesktop'
7
- import { useDesktopWorkspaceStore } from '../stores/storeDesktopWorkspace'
8
- import { useDesktopDefaultAppsStore } from '../stores/storeDesktopDefaultApps'
9
- import { registerDesktopPluginPinia } from '../../kit/defineDesktopApp'
10
-
11
- /** Bind Nuxt's Pinia instance for store composables outside component setup timing. */
12
- export function bindDesktopPinia(pinia: Pinia | undefined) {
13
- if (pinia) {
14
- setActivePinia(pinia)
15
- registerDesktopPluginPinia(pinia)
16
- }
17
- }
18
-
19
- /** Sync `appConfig.desktop` from runtime when the composable is not ready yet (early client plugins). */
20
- export function ensureAppConfigDesktop() {
21
- const runtimeConfig = useRuntimeConfig()
22
- const publicDesktop = runtimeConfig.public?.desktop
23
- if (!publicDesktop || typeof publicDesktop !== 'object') return undefined
24
-
25
- let appConfig: ReturnType<typeof useAppConfig> | undefined
26
- try {
27
- appConfig = useAppConfig()
28
- } catch {
29
- return publicDesktop as DesktopConfig
30
- }
31
-
32
- if (!appConfig) return publicDesktop as DesktopConfig
33
-
34
- if (!appConfig.desktop) {
35
- appConfig.desktop = publicDesktop as DesktopConfig
36
- }
37
-
38
- return appConfig.desktop as DesktopConfig
39
- }
40
-
41
- function mergeShellKeysOntoAppConfig() {
42
- if (import.meta.server) return
43
-
44
- const desktopManager = useDesktopManager()
45
- const desktop = ensureAppConfigDesktop()
46
- if (!desktop) return
47
-
48
- desktopManager.setConfig({
49
- windows: desktop.windows ? toRaw(desktop.windows) : undefined,
50
- systemBar: desktop.systemBar ? toRaw(desktop.systemBar) : undefined,
51
- dockBar: desktop.dockBar ? toRaw(desktop.dockBar) : undefined,
52
- workspaces: desktop.workspaces ? toRaw(desktop.workspaces) : undefined,
53
- })
54
- }
55
-
56
- /** Re-run appConfig shell merge when `useAppConfig()` was not ready during early plugins. */
57
- export function syncDesktopShellAppConfig() {
58
- mergeShellKeysOntoAppConfig()
59
- }
60
-
61
- /** Kernel shell bootstrap: workspaces, default apps, merged shell config on appConfig. */
62
- export function initDesktopShell() {
63
- if (import.meta.server) return
64
-
65
- const desktopStore = useDesktopStore()
66
- const desktopWorkspaceStore = useDesktopWorkspaceStore()
67
- const runtimeConfig = useRuntimeConfig()
68
- const desktopDefaultAppsStore = useDesktopDefaultAppsStore()
69
-
70
- if (desktopStore.$persistedState) {
71
- desktopStore.$persistedState.isReady().then(() => {
72
- desktopWorkspaceStore.setupWorkspaces()
73
- })
74
- } else {
75
- desktopWorkspaceStore.setupWorkspaces()
76
- }
77
-
78
- desktopDefaultAppsStore.loadDefaultAppsFromConfig(runtimeConfig)
79
- mergeShellKeysOntoAppConfig()
80
- }
@@ -1,57 +0,0 @@
1
- import {
2
- LEGACY_STORE_ID_MAP,
3
- STORE_ID_MIGRATION_FLAG,
4
- legacyApplicationStoreIdToNew,
5
- } from '../stores/storeIds'
6
-
7
- function migrateStorageKey(
8
- storage: Storage,
9
- legacyId: string,
10
- newId: string,
11
- ) {
12
- const legacyValue = storage.getItem(legacyId)
13
- if (legacyValue === null) return
14
-
15
- if (storage.getItem(newId) !== null) {
16
- storage.removeItem(legacyId)
17
- return
18
- }
19
-
20
- storage.setItem(newId, legacyValue)
21
- storage.removeItem(legacyId)
22
- }
23
-
24
- function collectLegacyApplicationKeys(storage: Storage) {
25
- const keys: string[] = []
26
-
27
- for (let index = 0; index < storage.length; index++) {
28
- const key = storage.key(index)
29
- if (key && legacyApplicationStoreIdToNew(key)) {
30
- keys.push(key)
31
- }
32
- }
33
-
34
- return keys
35
- }
36
-
37
- /**
38
- * One-shot migration of persisted Pinia state from legacy `owd/*` store ids
39
- * to `desktop/*`. Runs before shell init so module-persistence hydrates new keys.
40
- */
41
- export function migratePersistedStoreIds(storage: Storage = localStorage) {
42
- if (typeof storage?.getItem !== 'function') return
43
- if (storage.getItem(STORE_ID_MIGRATION_FLAG) === 'done') return
44
-
45
- for (const [legacyId, newId] of Object.entries(LEGACY_STORE_ID_MAP)) {
46
- migrateStorageKey(storage, legacyId, newId)
47
- }
48
-
49
- for (const legacyId of collectLegacyApplicationKeys(storage)) {
50
- const newId = legacyApplicationStoreIdToNew(legacyId)
51
- if (newId) {
52
- migrateStorageKey(storage, legacyId, newId)
53
- }
54
- }
55
-
56
- storage.setItem(STORE_ID_MIGRATION_FLAG, 'done')
57
- }
@@ -1,25 +0,0 @@
1
- export function normalizeApplicationConfig(
2
- config: ApplicationConfig,
3
- ): ApplicationConfig {
4
- const normalizedEntries: Record<string, ApplicationEntry> = {}
5
-
6
- if (config.entries) {
7
- for (const [key, entry] of Object.entries(config.entries)) {
8
- normalizedEntries[key] = {
9
- ...entry,
10
- title: entry.title ?? config.title,
11
- icon: entry.icon ?? config.icon,
12
- category: entry.category ?? config.category,
13
- visibility: entry.visibility ?? 'primary',
14
- }
15
- }
16
- }
17
-
18
- return {
19
- ...config,
20
- version: config.version ?? 'unknown',
21
- description: config.description ?? '',
22
- category: config.category ?? 'other',
23
- entries: normalizedEntries,
24
- }
25
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Renders a DOM subtree to a canvas via html2canvas (optional dependency).
3
- * Used for workspace overview thumbnails; returns null if capture fails or html2canvas is missing.
4
- */
5
- export async function captureElementToCanvas(
6
- element: HTMLElement | null | undefined,
7
- options?: Record<string, unknown>,
8
- ): Promise<HTMLCanvasElement | null> {
9
- if (!element || typeof window === 'undefined') {
10
- return null
11
- }
12
- try {
13
- const { default: html2canvas } = await import('html2canvas')
14
- return await html2canvas(element, {
15
- allowTaint: true,
16
- ...(options as object),
17
- })
18
- } catch {
19
- return null
20
- }
21
- }
@@ -1,26 +0,0 @@
1
- export function deepClone<T>(obj: T): T {
2
- return JSON.parse(JSON.stringify(obj))
3
- }
4
-
5
- export function deepEqual(obj1: any, obj2: any) {
6
- const keys1 = Object.keys(obj1)
7
- const keys2 = Object.keys(obj2)
8
- if (keys1.length !== keys2.length) {
9
- return false
10
- }
11
- for (const key of keys1) {
12
- if (!obj2.hasOwnProperty(key)) {
13
- return false
14
- }
15
- if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
16
- if (!deepEqual(obj1[key], obj2[key])) {
17
- return false
18
- }
19
- } else {
20
- if (obj1[key] !== obj2[key]) {
21
- return false
22
- }
23
- }
24
- }
25
- return true
26
- }
@@ -1,30 +0,0 @@
1
- export function isDebugMode() {
2
- return import.meta.env.MODE === 'development'
3
- }
4
-
5
- export function debugLog(...messages: any[]) {
6
- if (!isDebugMode()) {
7
- return false
8
- }
9
-
10
- console.log('[OWD]', ...messages)
11
- return true
12
- }
13
-
14
- export function debugWarn(...messages: any[]) {
15
- if (!isDebugMode()) {
16
- return false
17
- }
18
-
19
- console.warn('[OWD]', ...messages)
20
- return true
21
- }
22
-
23
- export function debugError(...messages: any[]) {
24
- if (!isDebugMode()) {
25
- return false
26
- }
27
-
28
- console.error('[OWD]', ...messages)
29
- return true
30
- }
@@ -1,57 +0,0 @@
1
- import type { DesktopWorkAreaRect, WindowLayout } from '@owdproject/core'
2
- import {
3
- WINDOW_SNAP_EDGE_PX,
4
- WORKSPACE_EDGE_DROP_PX,
5
- } from '../constants/shellLayout'
6
- import { workAreaBottom, workAreaRight } from './utilWindowLayout'
7
-
8
- export type SnapZoneHint = Exclude<WindowLayout, 'normal'>
9
-
10
- export type DetectSnapZoneOptions = {
11
- edgePx?: number
12
- /** When true, left/right half snap is suppressed in the outer workspace-edge band. */
13
- deferSideSnapForWorkspaceEdge?: boolean
14
- }
15
-
16
- /**
17
- * Resolve snap zone from pointer position and shell work area.
18
- * Returns null when the pointer is not in a snap band.
19
- */
20
- export function detectSnapZone(
21
- clientX: number,
22
- clientY: number,
23
- workArea: DesktopWorkAreaRect,
24
- options?: DetectSnapZoneOptions,
25
- ): SnapZoneHint | null {
26
- const edge = options?.edgePx ?? WINDOW_SNAP_EDGE_PX
27
- const { x, y, width, height } = workArea
28
-
29
- if (width <= 0 || height <= 0) {
30
- return null
31
- }
32
-
33
- const bottom = workAreaBottom(workArea)
34
- const right = workAreaRight(workArea)
35
-
36
- const nearTop = clientY <= y + edge
37
- const nearBottom = clientY >= bottom - edge
38
- const nearLeft = clientX <= x + edge
39
- const nearRight = clientX >= right - edge
40
-
41
- const inWorkspaceEdgeBand =
42
- options?.deferSideSnapForWorkspaceEdge === true &&
43
- typeof globalThis !== 'undefined' &&
44
- (clientX <= WORKSPACE_EDGE_DROP_PX ||
45
- clientX >= globalThis.innerWidth - WORKSPACE_EDGE_DROP_PX)
46
-
47
- if (nearTop && nearLeft) return 'top-left'
48
- if (nearTop && nearRight) return 'top-right'
49
- if (nearBottom && nearLeft) return 'bottom-left'
50
- if (nearBottom && nearRight) return 'bottom-right'
51
- if (nearTop) return 'maximize'
52
- if (nearBottom) return 'bottom-half'
53
- if (nearLeft && !inWorkspaceEdgeBand) return 'left-half'
54
- if (nearRight && !inWorkspaceEdgeBand) return 'right-half'
55
-
56
- return null
57
- }
@@ -1,6 +0,0 @@
1
- export function shellEscape(str: string): string {
2
- if (str === '') {
3
- return "''";
4
- }
5
- return `${str.replace(/'/g, `'\\''`)}`;
6
- }
@@ -1,15 +0,0 @@
1
- // support for controller-less windows
2
- // (for example: dummy windows in docs)
3
- export function handleWindowControllerProps(windowController: any) {
4
- if (windowController.instanced) {
5
- return windowController
6
- }
7
-
8
- return {
9
- ...windowController,
10
- ...windowController.config,
11
- state: {
12
- ...windowController.config,
13
- },
14
- }
15
- }