@owdproject/core 3.0.0-alpha.0

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 (37) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +141 -0
  3. package/index.ts +10 -0
  4. package/module/index.ts +146 -0
  5. package/package.json +45 -0
  6. package/runtime/components/Core/Application/CoreApplicationRender.vue +17 -0
  7. package/runtime/components/Core/Application/CoreApplicationWindowsRender.vue +19 -0
  8. package/runtime/components/Core/Background/CoreBackground.vue +17 -0
  9. package/runtime/components/Core/Desktop/CoreDesktop.vue +77 -0
  10. package/runtime/components/Core/Explorer/CoreExplorerFile.vue +67 -0
  11. package/runtime/components/Core/Explorer/CoreExplorerFolder.vue +11 -0
  12. package/runtime/components/Core/Time/CoreTime.vue +53 -0
  13. package/runtime/components/Core/Window/CoreWindow.vue +157 -0
  14. package/runtime/components/Core/Window/CoreWindowContent.vue +30 -0
  15. package/runtime/components/Core/Window/CoreWindowNav.vue +43 -0
  16. package/runtime/composables/useAppEntries.ts +21 -0
  17. package/runtime/composables/useApplicationManager.ts +7 -0
  18. package/runtime/composables/useApplicationState.ts +19 -0
  19. package/runtime/composables/useDesktopManager.ts +7 -0
  20. package/runtime/composables/useTerminalManager.ts +3 -0
  21. package/runtime/core/controllers/ApplicationController.ts +209 -0
  22. package/runtime/core/controllers/WindowController.ts +413 -0
  23. package/runtime/core/managers/ApplicationManager.ts +256 -0
  24. package/runtime/core/managers/DesktopManager.ts +41 -0
  25. package/runtime/plugins/resize.client.ts +6 -0
  26. package/runtime/stores/storeDesktop.ts +39 -0
  27. package/runtime/stores/storeDesktopVolume.ts +17 -0
  28. package/runtime/stores/storeDesktopWindow.ts +20 -0
  29. package/runtime/stores/storeDesktopWorkspace.ts +59 -0
  30. package/runtime/utils/utilsCommon.ts +35 -0
  31. package/runtime/utils/utilsDebug.ts +30 -0
  32. package/runtime/utils/utilsDesktop.ts +12 -0
  33. package/runtime/utils/utilsTerminal.ts +5 -0
  34. package/runtime/utils/utilsWindow.ts +14 -0
  35. package/tsconfig.json +3 -0
  36. package/types/index.d.ts +9 -0
  37. package/types/owd.d.ts +313 -0
@@ -0,0 +1,39 @@
1
+ import {defineStore} from "pinia"
2
+ import {ref} from "@vue/reactivity"
3
+
4
+ export const useDesktopStore = defineStore('owd/desktop', () => {
5
+ const state = ref<{
6
+ workspace: {
7
+ overview: boolean
8
+ active: string
9
+ list: string[]
10
+ }
11
+ volume: {
12
+ master: number
13
+ }
14
+ window: {
15
+ positionZ: number
16
+ }
17
+ }>({
18
+ workspace: {
19
+ overview: false,
20
+ active: '',
21
+ list: [],
22
+ },
23
+ volume: {
24
+ master: 100,
25
+ },
26
+ window: {
27
+ positionZ: 10
28
+ }
29
+ })
30
+
31
+ return {
32
+ state
33
+ }
34
+ }, {
35
+ // @ts-expect-error
36
+ persistedState: {
37
+ persist: true
38
+ },
39
+ })
@@ -0,0 +1,17 @@
1
+ import {defineStore} from "pinia"
2
+ import {computed} from "@vue/reactivity"
3
+ import {useDesktopStore} from "../stores/storeDesktop"
4
+
5
+ export const useDesktopVolumeStore = defineStore('owd/desktop/volume', () => {
6
+ const desktopStore = useDesktopStore()
7
+
8
+ const master = computed(() => desktopStore.state.volume.master)
9
+
10
+ function setMasterVolume(value: number) {
11
+ desktopStore.state.volume.master = value
12
+ }
13
+
14
+ return {
15
+ master
16
+ }
17
+ })
@@ -0,0 +1,20 @@
1
+ import {defineStore} from "pinia"
2
+ import {computed} from "@vue/reactivity"
3
+ import {useDesktopStore} from "../stores/storeDesktop"
4
+
5
+ export const useDesktopWindowStore = defineStore('owd/desktop/window', () => {
6
+ const desktopStore = useDesktopStore()
7
+
8
+ const positionZ = computed(() => desktopStore.state.window.positionZ)
9
+
10
+ function incrementPositionZ() {
11
+ desktopStore.state.window.positionZ++
12
+
13
+ return desktopStore.state.window.positionZ
14
+ }
15
+
16
+ return {
17
+ positionZ,
18
+ incrementPositionZ
19
+ }
20
+ })
@@ -0,0 +1,59 @@
1
+ import {defineStore} from "pinia"
2
+ import {computed} from "@vue/reactivity"
3
+ import {nanoid} from "nanoid";
4
+ import {useDesktopStore} from "../stores/storeDesktop"
5
+
6
+ export const useDesktopWorkspaceStore = defineStore('owd/desktop/workspace', () => {
7
+ const desktopStore = useDesktopStore()
8
+
9
+ const active = computed(() => {
10
+ return desktopStore.state.workspace.active
11
+ })
12
+
13
+ const overview = computed(() => {
14
+ return desktopStore.state.workspace.overview
15
+ })
16
+
17
+ const list = computed(() => {
18
+ return desktopStore.state.workspace.list
19
+ })
20
+
21
+ function setupWorkspaces() {
22
+ if (desktopStore.state.workspace.list.length === 0) {
23
+ createWorkspace()
24
+ desktopStore.state.workspace.active = desktopStore.state.workspace.list[0] as string
25
+ }
26
+
27
+ if (desktopStore.state.workspace.list.length === 1) {
28
+ createWorkspace()
29
+ }
30
+ }
31
+
32
+ function setOverview(value: boolean) {
33
+ desktopStore.state.workspace.overview = value
34
+ }
35
+
36
+ function setWorkspace(value: string) {
37
+ desktopStore.state.workspace.active = value
38
+ }
39
+
40
+ function createWorkspace() {
41
+ desktopStore.state.workspace.list.push(nanoid(8))
42
+ }
43
+
44
+ const workspaceActiveIndex = computed(() => {
45
+ return desktopStore.state.workspace.list.findIndex(
46
+ workspace => workspace === desktopStore.state.workspace.active
47
+ )
48
+ })
49
+
50
+ return {
51
+ active,
52
+ overview,
53
+ list,
54
+ workspaceActiveIndex,
55
+ setupWorkspaces,
56
+ setOverview,
57
+ setWorkspace,
58
+ }
59
+ })
@@ -0,0 +1,35 @@
1
+ export function deepClone(obj: any) {
2
+ return JSON.parse(JSON.stringify(obj))
3
+ }
4
+
5
+ export function deepMerge<T>(target: T, source: Partial<T>): T {
6
+ function isObject(value: any): value is Record<string, any> {
7
+ return (
8
+ value !== null &&
9
+ typeof value === 'object' &&
10
+ !Array.isArray(value) &&
11
+ !(value instanceof Date) &&
12
+ !(value instanceof RegExp)
13
+ )
14
+ }
15
+
16
+ if (isObject(target) && isObject(source)) {
17
+ const result = { ...target }
18
+
19
+ for (const key in source) {
20
+ const targetValue = (target as any)[key]
21
+ const sourceValue = (source as any)[key]
22
+
23
+ if (isObject(sourceValue) && isObject(targetValue)) {
24
+ // @ts-ignore
25
+ result[key] = deepMerge(targetValue, sourceValue)
26
+ } else {
27
+ result[key] = sourceValue
28
+ }
29
+ }
30
+
31
+ return result
32
+ }
33
+
34
+ return source as T
35
+ }
@@ -0,0 +1,30 @@
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
+ }
@@ -0,0 +1,12 @@
1
+ import {useApplicationManager} from "../composables/useApplicationManager";
2
+ import {useDesktopManager} from "../composables/useDesktopManager";
3
+
4
+ export function defineDesktopApp(config: ApplicationConfig) {
5
+ const applicationManager = useApplicationManager()
6
+ return applicationManager.defineApp(config.id, config)
7
+ }
8
+
9
+ export function defineDesktopConfig(config: DesktopConfig) {
10
+ const desktopManager = useDesktopManager()
11
+ desktopManager.setConfig(config)
12
+ }
@@ -0,0 +1,5 @@
1
+ export function parseInput(input: string): { command: string; args: string[] } | null {
2
+ const match = input.match(/(?:[^\s"]+|"[^"]*")+/g)
3
+ if (!match) return null
4
+ return { command: match[0], args: match.slice(1).map(arg => arg.replace(/"/g, "")) }
5
+ }
@@ -0,0 +1,14 @@
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
+ state: {
11
+ ...windowController.config,
12
+ },
13
+ }
14
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../.nuxt/tsconfig.json",
3
+ }
@@ -0,0 +1,9 @@
1
+ declare module 'nuxt/schema' {
2
+ interface AppConfig {
3
+ owd: {
4
+ apps: string[]
5
+ }
6
+ }
7
+ }
8
+
9
+ export {}
package/types/owd.d.ts ADDED
@@ -0,0 +1,313 @@
1
+ interface IApplicationManager {
2
+ apps: Map<string, IApplicationController>
3
+ appsRunning: Reactive<IApplicationController>
4
+
5
+ importApps()
6
+
7
+ get appsEntries(): Reactive<ApplicationEntry[]>
8
+ get windowsOpened(): Reactive<IWindowController>
9
+ get appCategories(): string[]
10
+ get appsByCategory(): { [category: string]: IApplicationController[] }
11
+
12
+ defineApp(appId: string, config: ApplicationConfig): Promise<IApplicationController>
13
+ closeApp(id: string): void
14
+
15
+ execAppCommand(appId: string, command: string): Promise<IApplicationController | undefined>
16
+
17
+ isAppDefined(id: string): boolean
18
+ isAppRunning(id: string): boolean
19
+ }
20
+
21
+ type ApplicationCommand = (app: IApplicationController, args: any) => void;
22
+
23
+ interface ApplicationConfig {
24
+ id: string
25
+ title: string
26
+ icon?: string
27
+ category?: string
28
+ version?: string
29
+ description?: string
30
+ provides?: ApplicationConfigProvide
31
+ singleton?: boolean
32
+ meta?: IApplicationMeta
33
+ permissions?: ApplicationPermission[];
34
+ windows?: { [key: string]: WindowConfig }
35
+ entries: { [key: string]: ApplicationEntry }
36
+ commands?: { [key: string]: ApplicationCommand }
37
+
38
+ onReady?(app: IApplicationController): void | Promise<void>
39
+ onLaunch?(app: IApplicationController): void | Promise<void>
40
+ onRestore?(app: IApplicationController): void | Promise<void>
41
+ onClose?(app: IApplicationController): void | Promise<void>
42
+ }
43
+
44
+ interface ApplicationConfigProvide {
45
+ name: string
46
+ entry: string
47
+ }
48
+
49
+ type IApplicationMeta = { [key: string]: any }
50
+
51
+ interface IApplicationController {
52
+ id: string
53
+ config: ApplicationConfig
54
+ get meta(): { [key: string]: any }
55
+ store: Pinia
56
+ windows: Reactive<Map<string, IWindowController>>
57
+
58
+ isRunning: boolean
59
+ setRunning(value: boolean): void
60
+
61
+ initApplication(): Promise<void>
62
+ restoreApplication(): Promise<boolean>
63
+
64
+ openWindow(model: string, windowStoredState?: WindowStoredState, meta?: {
65
+ isRestoring?: boolean
66
+ })
67
+
68
+ closeWindow(windowId: string): void
69
+ closeAllWindows(): void
70
+
71
+ get windowsOpened(): Reactive<Map<string, IWindowController>>
72
+ }
73
+
74
+ interface IWindowController {
75
+ application: IApplicationController
76
+ instanced: boolean
77
+ model: string
78
+
79
+ config: WindowConfig
80
+ override: WindowOverride
81
+ get state(): WindowState
82
+
83
+ // common
84
+ get title(): string
85
+ get icon(): string|undefined
86
+
87
+ // sizes
88
+ get width(): WindowSizeValue
89
+
90
+ get maxWidth(): WindowSizeValue
91
+
92
+ get minWidth(): WindowSizeValue
93
+
94
+ get height(): WindowSizeValue
95
+
96
+ get maxHeight(): WindowSizeValue
97
+
98
+ get minHeight(): WindowSizeValue
99
+
100
+ // minimize
101
+ get isMinimizable(): boolean
102
+
103
+ // maximize
104
+ get isMaximizable(): boolean
105
+
106
+ get isMaximized(): boolean
107
+
108
+ // destroy
109
+ get isDestroyable(): boolean
110
+
111
+ // draggable
112
+ get isDraggable(): boolean
113
+
114
+ // resizable
115
+ get isResizable(): boolean
116
+
117
+ get actions(): {
118
+ // position
119
+ setActive(value: boolean)
120
+ setFocus(value: boolean)
121
+ bringToFront()
122
+ setPosition(data: WindowPosition)
123
+
124
+ // size
125
+ setSize(data: WindowSize)
126
+
127
+ // minimize
128
+ minimize(): boolean
129
+
130
+ // maximize
131
+ toggleMaximize(): boolean
132
+ maximize(): boolean
133
+ unmaximize(): boolean
134
+
135
+ // destroy
136
+ destroy(): boolean
137
+
138
+ // workspace
139
+ setWorkspace(workspaceId: string)
140
+
141
+ // override
142
+ setTitleOverride(title: string|undefined): void
143
+ resetTitleOverride(): void
144
+ }
145
+ }
146
+
147
+ interface WindowContent {
148
+ padded?: boolean
149
+ centered?: boolean
150
+ }
151
+
152
+ interface WindowConfig {
153
+ title?: string
154
+ category?: string
155
+ icon?: string
156
+ pinned?: boolean
157
+
158
+ component?: Raw<Component>
159
+
160
+ // position
161
+ position?: WindowPosition
162
+
163
+ // sizes
164
+ size: WindowSize
165
+
166
+ // minimize
167
+ minimizable?: boolean
168
+
169
+ // maximize
170
+ maximized?: boolean
171
+ maximizable?: boolean
172
+
173
+ // destroy
174
+ destroyable?: boolean
175
+
176
+ // draggable
177
+ draggable?: boolean
178
+
179
+ // draggable
180
+ resizable?: boolean
181
+ }
182
+
183
+ interface WindowStoredState {
184
+ model: string,
185
+ state: WindowState
186
+ }
187
+
188
+ interface WindowOverride {
189
+ title?: undefined|string
190
+ icon?: undefined|string
191
+ }
192
+
193
+ interface WindowState {
194
+ id: string
195
+ createdAt: number
196
+
197
+ category?: string
198
+ pinned?: boolean
199
+ workspace: string
200
+
201
+ // position
202
+ position?: WindowPosition
203
+
204
+ // sizes
205
+ size?: WindowSize
206
+
207
+ // focused
208
+ focused: boolean
209
+
210
+ // minimize
211
+ active?: boolean
212
+ minimizable?: boolean
213
+
214
+ // maximize
215
+ maximized?: boolean
216
+ maximizable?: boolean
217
+
218
+ // destroy
219
+ destroyable?: boolean
220
+
221
+ // draggable
222
+ draggable?: boolean
223
+
224
+ // draggable
225
+ resizable?: boolean
226
+ }
227
+
228
+ interface WindowSize {
229
+ width?: WindowSizeValue
230
+ height?: WindowSizeValue
231
+ minWidth?: WindowSizeValue
232
+ minHeight?: WindowSizeValue
233
+ maxWidth?: WindowSizeValue
234
+ maxHeight?: WindowSizeValue
235
+ }
236
+
237
+ interface WindowPosition {
238
+ x?: number
239
+ y?: number
240
+ z?: number
241
+ }
242
+
243
+ type WindowSizeValue = number|string|undefined
244
+
245
+ interface ApplicationEntry {
246
+ title?: string
247
+ icon?: string
248
+ category?: string
249
+ command: string | any
250
+ }
251
+
252
+ interface ApplicationEntryWithInherited extends ApplicationEntry {
253
+ application: IApplicationController
254
+ }
255
+
256
+ // DESKTOP
257
+
258
+ interface IDesktopManager {
259
+ defaultApps: DefaultAppsConfig
260
+
261
+ getDefaultApp(feature: string)
262
+ setDefaultApp(feature: string, application: IApplicationController, entry: ApplicationEntry)
263
+ }
264
+
265
+ interface DesktopConfig {
266
+ name: string
267
+ compatibility: string
268
+ defaultApps?: DefaultAppsConfig
269
+ features?: string[]
270
+ systemBar?: DesktopSystemBarConfig
271
+ dockBar?: DesktopDockBarConfig
272
+ }
273
+
274
+ interface DesktopWindowsConfig {
275
+ position: 'relative' | 'absolute' | 'fixed'
276
+ }
277
+
278
+ interface DesktopDockBarConfig {
279
+ enabled?: boolean
280
+ position?: 'top' | 'bottom'
281
+ }
282
+
283
+ interface DesktopSystemBarConfig {
284
+ enabled?: boolean
285
+ position?: 'top' | 'bottom'
286
+ startButton?: boolean
287
+ }
288
+
289
+ // TERMINAL
290
+
291
+ interface CommandFn {
292
+ fn: (app: IApplicationController, args: string[]) => string | CommandOutput | void
293
+ app: IApplicationController
294
+ }
295
+
296
+ interface CommandOutput {
297
+ text: string
298
+ isError?: boolean
299
+ }
300
+
301
+ // DEFAULT APP
302
+
303
+ interface DefaultAppsConfig {
304
+ terminal?: DefaultAppConfig
305
+ browser?: DefaultAppConfig
306
+ editor?: DefaultAppConfig
307
+ [key: string]: DefaultAppConfig
308
+ }
309
+
310
+ interface DefaultAppConfig {
311
+ application: IApplicationController
312
+ entry: ApplicationEntry
313
+ }