Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 7 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,18 @@ Orbit owns only the parts where product value lives - the clients, Satellite (vo

## Development

The workspace uses **pnpm** with a dependency catalog and **[vite-plus](https://github.com/vitejs/vite-plus)** (`vp`) as the task runner. Requires Node >= 24.
The workspace uses **[vite-plus](https://github.com/vitejs/vite-plus)** (`vp`) as the task runner. Requires Node >= 24.

```sh
pnpm install # install workspace dependencies
pnpm dev # web dev server (runs apps/web)
pnpm ready # gate: vp check && vp run -r test && vp run -r build
```

Scoped and recursive commands:
vp i # initialize the project
vp create # add a new package/app to the monorepo
vp run test # run every test suite

```sh
vp run web#dev # Vite dev server for the web app
vp run web#build # build the web app / PWA
vp run -r test # run every test suite
vp run -r build # build every package and app
vp run dev # start the apps/web dev server
vp run build # build the apps/web application
```

## Specification

The complete design spec - architecture, components, identity, clients, infrastructure, ADRs, and research tracks - lives in [orbit-spec](https://github.com/hivecom/orbit-spec). Start with the [Platform Comparison](https://github.com/hivecom/orbit-spec/blob/main/spec/01-architecture/05-platform-comparison.md) and [Design Philosophy](https://github.com/hivecom/orbit-spec/blob/main/spec/01-architecture/02-philosophy.md).
Use `vp test` inside an individual package when you want that package's local Vite/Vitest config, for example `packages/app` or `packages/platform`. From the workspace root, use `vp run -r test` so each package runs under its own test setup.

## License

Expand Down
14 changes: 7 additions & 7 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
"preview": "vp preview"
},
"dependencies": {
"core": "workspace:*",
"app": "workspace:*",
"platform": "workspace:*",
"vue": "^3.5.34"
"vue": "^3.5.38"
},
"devDependencies": {
"@types/node": "^24.12.3",
"@vitejs/plugin-vue": "^6.0.6",
"@types/node": "^24.13.2",
"@vitejs/plugin-vue": "^6.0.7",
"@vue/tsconfig": "^0.9.1",
"typescript": "~6.0.2",
"vite": "catalog:",
"typescript": "~6.0.3",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.2.1",
"vite-plus": "catalog:",
"vue-tsc": "^3.2.8"
"vue-tsc": "^3.3.5"
}
}
2 changes: 1 addition & 1 deletion apps/web/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { OrbitApp } from "core"
import { OrbitApp } from "app"
</script>

<template>
Expand Down
9 changes: 4 additions & 5 deletions apps/web/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { createApp } from "vue"
import { providePlatform, router } from "core"
import { createOrbitApp } from "app"
import { createWebPlatform } from "platform"
import App from "./App.vue"

const app = createApp(App)
app.use(router)
providePlatform(app, createWebPlatform())
const platform = createWebPlatform()
const app = createOrbitApp(App, platform)

app.mount("#app")
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
"private": true,
"type": "module",
"scripts": {
"test": "vp run -r test",
"ready": "vp check && vp run -r test && vp run -r build",
"dev": "vp run web#dev"
"prepare": "vp config",
"dev": "vp run web#dev",
"build": "vp run web#build"
},
"devDependencies": {
"vite-plus": "catalog:"
Expand Down
File renamed without changes.
8 changes: 3 additions & 5 deletions packages/core/README.md → packages/app/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# core
# Application core

The heart of the Orbit client. Every build target - web, desktop, and the embeddable widget - is served from this package with only the platform adapter swapped out. Application logic lives here, never in the entrypoints.
The heart of the Orbit client. Every build target - web, desktop, and the embeddable widget - is served from this package with only the platform adapter swapped out. Application logic lives here.

UI is built with [`@dolanske/vui`](https://github.com/Dolanske/vui); state uses Pinia.

Expand All @@ -9,14 +9,12 @@ UI is built with [`@dolanske/vui`](https://github.com/Dolanske/vui); state uses
Core never imports `@tauri-apps/api` or reaches into raw `navigator.*`. Instead it declares capability ports and consumes them through an injected `Platform`:

```ts
import { usePlatform } from "core"
import { usePlatform } from "app"

const platform = usePlatform()
await platform.notifications.requestPermission()
```

The seam is shaped by capability, not by platform - core asks a port to do a thing, it never asks "am I running in Tauri". A port an environment can't provide is `null`, and core degrades explicitly. Each entrypoint supplies a concrete adapter from `platform` and injects it once at boot via `providePlatform(app, ...)`.

## Commands

```sh
Expand Down
3 changes: 2 additions & 1 deletion packages/core/package.json → packages/app/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "core",
"name": "app",
"version": "0.0.0",
"private": true,
"type": "module",
Expand All @@ -12,6 +12,7 @@
"dependencies": {
"@dolanske/vui": "catalog:",
"pinia": "catalog:",
"platform": "workspace:*",
"vue": "^3.5.34",
"vue-router": "catalog:"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/app/src/components/OrbitApp.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import "../style/index.css"
</script>

<template>
<div class="ob-root">
<RouterView />
</div>
</template>
File renamed without changes.
4 changes: 4 additions & 0 deletions packages/app/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import OrbitApp from "./components/OrbitApp.vue"
import { createOrbitApp } from "./lib/setup.ts"

export { OrbitApp, createOrbitApp }
17 changes: 17 additions & 0 deletions packages/app/src/lib/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createApp, type Component } from "vue"
import { router } from "../router"
import { type Platform, PLATFORM_KEY } from "platform"

/**
* Creates an Orbit app.
*
* @param root Root component
* @param platform Platform adapter
* @returns Vue application instance
*/
export function createOrbitApp(root: Component, platform: Platform) {
const app = createApp(root)
app.use(router)
app.provide(PLATFORM_KEY, platform)
return app
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions packages/app/test/fixtures/TestApp.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import { usePlatform } from "platform"

const platform = usePlatform()
</script>

<template>
<div :data-test-target="platform.target" />
</template>
27 changes: 27 additions & 0 deletions packages/app/test/setup.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, expect, it } from "vite-plus/test"
import { createOrbitApp } from "../src/index.ts"
import { createWebPlatform } from "platform/src/web.ts"
import { PLATFORM_KEY } from "platform"
import { mount } from "@vue/test-utils"
import TestApp from "./fixtures/TestApp.vue"

describe("Setup Orbit application", () => {
it("should create an app instance with a web platform adapter", () => {
const platform = createWebPlatform()
const app = createOrbitApp(TestApp, platform)
expect(app._context.provides[PLATFORM_KEY]).toBe(platform)
})

it("should should be available within vue components when using usePlatform", () => {
const selector = mount(TestApp, {
global: {
provide: {
[PLATFORM_KEY]: createWebPlatform(),
},
},
})

const target = selector.get("[data-test-target]")
expect(target.attributes("data-test-target")).toBe("web")
})
})
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 0 additions & 15 deletions packages/core/src/components/OrbitApp.vue

This file was deleted.

5 changes: 0 additions & 5 deletions packages/core/src/index.ts

This file was deleted.

4 changes: 4 additions & 0 deletions packages/depot/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
*.log
.DS_Store
3 changes: 3 additions & 0 deletions packages/depot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Depot

Client-side communication layer between [orbit-depot](https://github.com/hivecom/orbit-depot) and Orbit's UI.
43 changes: 43 additions & 0 deletions packages/depot/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "depot",
"version": "0.0.0",
"description": "A starter for creating a TypeScript package.",
"homepage": "https://github.com/author/library#readme",
"bugs": {
"url": "https://github.com/author/library/issues"
},
"license": "MIT",
"author": "Author Name <author.name@mail.com>",
"repository": {
"type": "git",
"url": "git+https://github.com/author/library.git"
},
"files": [
"dist"
],
"type": "module",
"exports": {
".": "./dist/index.mjs",
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "vp pack",
"dev": "vp pack --watch",
"test": "vp test",
"check": "vp check",
"prepublishOnly": "vp run build"
},
"dependencies": {
"vitest": "catalog:"
},
"devDependencies": {
"@types/node": "^25.6.2",
"@typescript/native-preview": "7.0.0-dev.20260509.2",
"bumpp": "^11.1.0",
"typescript": "^6.0.3",
"vite-plus": "catalog:"
}
}
19 changes: 19 additions & 0 deletions packages/depot/src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Placeholder API that stays in sync with methods that Depot exposes

export const User = {
uploadStart: () => {},
upload: () => {},
delete: () => {},
}

export const Internal = {
keys: {
get: () => {},
post: () => {},
delete: (keyId: string) => {
void keyId
},
},
quota: () => {},
health: () => {},
}
3 changes: 3 additions & 0 deletions packages/depot/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { User, Internal } from "./api.ts"

export { User, Internal }
10 changes: 10 additions & 0 deletions packages/depot/test/api.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { describe, expect, it } from "vite-plus/test"
import { User } from "../src/api.ts"

describe("API tests", () => {
it("should have the expected API methods", () => {
expect(typeof User.uploadStart).toBe("function")
expect(typeof User.upload).toBe("function")
expect(typeof User.delete).toBe("function")
})
})
20 changes: 20 additions & 0 deletions packages/depot/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "esnext",
"lib": ["es2023"],
"moduleDetection": "force",
"module": "nodenext",
"moduleResolution": "nodenext",
"resolveJsonModule": true,
"types": ["node"],
"strict": true,
"noUnusedLocals": true,
"declaration": true,
"noEmit": true,
"allowImportingTsExtensions": true,
"esModuleInterop": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
}
}
17 changes: 17 additions & 0 deletions packages/depot/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineConfig } from "vite-plus"

export default defineConfig({
pack: {
dts: {
tsgo: true,
},
exports: true,
},
lint: {
options: {
typeAware: true,
typeCheck: true,
},
},
fmt: {},
})
1 change: 0 additions & 1 deletion packages/platform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"test": "vp test"
},
"dependencies": {
"core": "workspace:*",
"vue": "^3.5.34"
},
"devDependencies": {
Expand Down
14 changes: 14 additions & 0 deletions packages/platform/src/composables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { inject } from "vue"
import type { Platform } from "./types"
import { PLATFORM_KEY } from "./constants"

/**
* Access the injected platform adapter from a component or composable.
* */
export function usePlatform(): Platform {
const platform = inject<Platform>(PLATFORM_KEY)
if (!platform) {
throw new Error("No platform adapter provided. Make sure to provide a platform adapter during Orbit app initialization.")
}
return platform
}
4 changes: 4 additions & 0 deletions packages/platform/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { InjectionKey } from "vue"
import type { Platform } from "./types"

export const PLATFORM_KEY: InjectionKey<Platform> = Symbol("orbit-platform")
7 changes: 6 additions & 1 deletion packages/platform/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export { createWebPlatform } from "./web.ts"
import { createWebPlatform } from "./web"
import type { Platform } from "./types"
import { PLATFORM_KEY } from "./constants"
import { usePlatform } from "./composables"

export { createWebPlatform, type Platform, PLATFORM_KEY, usePlatform }
Loading
Loading