@dxos/halo 0.0.0 → 0.11.1

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/moon.yml CHANGED
@@ -1,11 +1,5 @@
1
1
  layer: library
2
2
  language: typescript
3
3
  tags:
4
- - ts-build
4
+ - ts-vite-build
5
5
  - pack
6
- tasks:
7
- compile:
8
- args:
9
- - '--entryPoint=src/index.ts'
10
- - '--injectGlobals'
11
- - '--platform=neutral'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/halo",
3
- "version": "0.0.0",
3
+ "version": "0.11.1",
4
4
  "description": "DXOS HALO",
5
5
  "homepage": "https://github.com/dxos/dxos/tree/main/packages/core/halo/halo#readme",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,14 +16,14 @@
16
16
  ".": {
17
17
  "source": "./src/index.ts",
18
18
  "types": "./dist/types/src/index.d.ts",
19
- "default": "./dist/lib/neutral/index.mjs"
19
+ "import": "./dist/lib/index.mjs"
20
20
  }
21
21
  },
22
22
  "types": "dist/types/src/index.d.ts",
23
23
  "dependencies": {
24
24
  "effect": "3.21.4",
25
- "@dxos/errors": "0.10.0",
26
- "@dxos/keys": "0.10.0"
25
+ "@dxos/errors": "0.11.1",
26
+ "@dxos/keys": "0.11.1"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
package/vite.config.ts ADDED
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { defineConfig } from '../../../../vite.base.config.ts';
6
+
7
+ export default defineConfig();
@@ -1,186 +0,0 @@
1
- import "@dxos/node-std/globals";
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, { get: all[name], enumerable: true });
6
- };
7
-
8
- // src/Identity.ts
9
- var Identity_exports = {};
10
- __export(Identity_exports, {
11
- Credential: () => Credential,
12
- DeviceInfo: () => DeviceInfo,
13
- DeviceKind: () => DeviceKind,
14
- Info: () => Info,
15
- Service: () => Service,
16
- create: () => create,
17
- credentials: () => credentials,
18
- devices: () => devices,
19
- getDevicesSnapshot: () => getDevicesSnapshot,
20
- getSnapshot: () => getSnapshot,
21
- grantServiceAccess: () => grantServiceAccess,
22
- identity: () => identity,
23
- invitations: () => invitations,
24
- join: () => join,
25
- recover: () => recover,
26
- share: () => share,
27
- updateProfile: () => updateProfile
28
- });
29
- import * as Context from "effect/Context";
30
- import * as Effect from "effect/Effect";
31
- import * as Schema from "effect/Schema";
32
- import * as Stream from "effect/Stream";
33
- import { IdentityDid } from "@dxos/keys";
34
- var DeviceKind = Schema.Literal("unknown", "browser", "native", "mobile", "agent", "agent-managed");
35
- var Info = Schema.Struct({
36
- did: IdentityDid,
37
- /** Hex-encoded identity (credential) key, when known. */
38
- identityKey: Schema.optional(Schema.String),
39
- displayName: Schema.optional(Schema.String),
40
- /** Arbitrary profile metadata. */
41
- data: Schema.optional(Schema.Record({
42
- key: Schema.String,
43
- value: Schema.Any
44
- }))
45
- });
46
- var DeviceInfo = Schema.Struct({
47
- /** Hex-encoded device key. */
48
- key: Schema.String,
49
- kind: Schema.optional(DeviceKind),
50
- label: Schema.optional(Schema.String),
51
- /** Whether this device is the local (current) device. */
52
- current: Schema.Boolean
53
- });
54
- var Credential = Schema.Struct({
55
- /** Hex-encoded credential id, when assigned. */
56
- id: Schema.optional(Schema.String),
57
- /** The subject assertion's `@type` (e.g. `dxos.halo.credentials.IdentityRecovery`). */
58
- type: Schema.String,
59
- issuanceDate: Schema.optional(Schema.DateFromSelf)
60
- });
61
- var Service = class extends Context.Tag("@dxos/halo/Identity")() {
62
- };
63
- var identity = Stream.unwrap(Effect.map(Service, (service) => service.identity));
64
- var getSnapshot = Effect.map(Service, (service) => service.getSnapshot());
65
- var create = (options) => Effect.flatMap(Service, (service) => service.create(options));
66
- var recover = (args) => Effect.flatMap(Service, (service) => service.recover(args));
67
- var updateProfile = (profile) => Effect.flatMap(Service, (service) => service.updateProfile(profile));
68
- var devices = Stream.unwrap(Effect.map(Service, (service) => service.devices));
69
- var getDevicesSnapshot = Effect.map(Service, (service) => service.getDevicesSnapshot());
70
- var credentials = Stream.unwrap(Effect.map(Service, (service) => service.credentials));
71
- var grantServiceAccess = (options) => Effect.flatMap(Service, (service) => service.grantServiceAccess(options));
72
- var share = (options) => Effect.flatMap(Service, (service) => service.share(options));
73
- var join = (code2) => Effect.flatMap(Service, (service) => service.join(code2));
74
- var invitations = Stream.unwrap(Effect.map(Service, (service) => service.invitations));
75
-
76
- // src/Invitation.ts
77
- var Invitation_exports = {};
78
- __export(Invitation_exports, {
79
- authenticate: () => authenticate,
80
- cancel: () => cancel,
81
- code: () => code,
82
- events: () => events
83
- });
84
- var authenticate = (flow, code2) => flow.authenticate(code2);
85
- var cancel = (flow) => flow.cancel();
86
- var events = (flow) => flow.events;
87
- var code = (flow) => flow.code;
88
-
89
- // src/Space.ts
90
- var Space_exports = {};
91
- __export(Space_exports, {
92
- Access: () => Access,
93
- EdgeReplication: () => EdgeReplication,
94
- Info: () => Info2,
95
- Member: () => Member,
96
- MembershipPolicy: () => MembershipPolicy,
97
- Service: () => Service2,
98
- State: () => State,
99
- create: () => create2,
100
- exportSpace: () => exportSpace,
101
- get: () => get,
102
- importSpace: () => importSpace,
103
- invitations: () => invitations2,
104
- join: () => join2,
105
- members: () => members,
106
- removeMember: () => removeMember,
107
- setEdgeReplication: () => setEdgeReplication,
108
- share: () => share2,
109
- spaces: () => spaces,
110
- updateMemberRole: () => updateMemberRole,
111
- waitReady: () => waitReady
112
- });
113
- import * as Context2 from "effect/Context";
114
- import * as Effect2 from "effect/Effect";
115
- import * as Schema2 from "effect/Schema";
116
- import * as Stream2 from "effect/Stream";
117
- import { IdentityDid as IdentityDid2, SpaceId } from "@dxos/keys";
118
- var Access = Schema2.Literal("pull", "read", "edit", "admin");
119
- var State = Schema2.Literal("inactive", "closed", "ready");
120
- var MembershipPolicy = Schema2.Literal("invite", "locked");
121
- var EdgeReplication = Schema2.Literal("disabled", "enabled");
122
- var Member = Schema2.Struct({
123
- /** DID of the member identity, when known. */
124
- did: Schema2.optional(IdentityDid2),
125
- /** Hex-encoded identity key of the member, for avatar/presence keying. */
126
- identityKey: Schema2.optional(Schema2.String),
127
- displayName: Schema2.optional(Schema2.String),
128
- /** Arbitrary profile metadata (e.g. avatar emoji, hue). */
129
- data: Schema2.optional(Schema2.Record({
130
- key: Schema2.String,
131
- value: Schema2.Any
132
- })),
133
- role: Access,
134
- /** Whether the member is currently online. */
135
- online: Schema2.Boolean
136
- });
137
- var Info2 = Schema2.Struct({
138
- id: SpaceId,
139
- name: Schema2.optional(Schema2.String),
140
- state: State
141
- });
142
- var Service2 = class extends Context2.Tag("@dxos/halo/Space")() {
143
- };
144
- var spaces = Stream2.unwrap(Effect2.map(Service2, (service) => service.spaces));
145
- var get = (id) => Effect2.flatMap(Service2, (service) => service.get(id));
146
- var create2 = (options) => Effect2.flatMap(Service2, (service) => service.create(options));
147
- var waitReady = (id) => Effect2.flatMap(Service2, (service) => service.waitReady(id));
148
- var setEdgeReplication = (id, setting) => Effect2.flatMap(Service2, (service) => service.setEdgeReplication(id, setting));
149
- var members = (id) => Stream2.unwrap(Effect2.map(Service2, (service) => service.members(id)));
150
- var updateMemberRole = (id, subject, role) => Effect2.flatMap(Service2, (service) => service.updateMemberRole(id, subject, role));
151
- var removeMember = (id, subject) => Effect2.flatMap(Service2, (service) => service.removeMember(id, subject));
152
- var share2 = (id, options) => Effect2.flatMap(Service2, (service) => service.share(id, options));
153
- var join2 = (code2) => Effect2.flatMap(Service2, (service) => service.join(code2));
154
- var invitations2 = (id) => Stream2.unwrap(Effect2.map(Service2, (service) => service.invitations(id)));
155
- var exportSpace = (id) => Effect2.flatMap(Service2, (service) => service.export(id));
156
- var importSpace = (archive, options) => Effect2.flatMap(Service2, (service) => service.import(archive, options));
157
-
158
- // src/errors.ts
159
- import { BaseError } from "@dxos/errors";
160
- var NotAuthorizedError = class extends BaseError.extend("NotAuthorizedError", "Not authorized") {
161
- };
162
- var UnknownPrincipalError = class extends BaseError.extend("UnknownPrincipalError", "Unknown principal") {
163
- };
164
- var InvalidSignatureError = class extends BaseError.extend("InvalidSignatureError", "Invalid signature") {
165
- };
166
- var MissingDependencyError = class extends BaseError.extend("MissingDependencyError", "Missing dependency") {
167
- };
168
- var IdentityError = class extends BaseError.extend("IdentityError", "Identity operation failed") {
169
- };
170
- var SpaceError = class extends BaseError.extend("SpaceError", "Space operation failed") {
171
- };
172
- var InvitationError = class extends BaseError.extend("InvitationError", "Invitation operation failed") {
173
- };
174
- export {
175
- Identity_exports as Identity,
176
- IdentityError,
177
- InvalidSignatureError,
178
- Invitation_exports as Invitation,
179
- InvitationError,
180
- MissingDependencyError,
181
- NotAuthorizedError,
182
- Space_exports as Space,
183
- SpaceError,
184
- UnknownPrincipalError
185
- };
186
- //# sourceMappingURL=index.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/Identity.ts", "../../../src/Invitation.ts", "../../../src/Space.ts", "../../../src/errors.ts"],
4
- "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as Stream from 'effect/Stream';\n\nimport { IdentityDid } from '@dxos/keys';\n\nimport { type IdentityError } from './errors';\nimport * as Invitation from './Invitation';\n\n/**\n * Device kind (platform / host class). Replaces the legacy protobuf `DeviceType` enum;\n * `agent`/`agent-managed` denote EDGE- or Hub-hosted agent devices.\n */\nexport const DeviceKind = Schema.Literal('unknown', 'browser', 'native', 'mobile', 'agent', 'agent-managed');\nexport type DeviceKind = typeof DeviceKind.Type;\n\n/**\n * Public view of the local identity. Keyed by the DID; `identityKey` (hex) is retained for\n * consumers that seed deterministic UI (avatar/hue) or address the legacy credential key.\n * `data` carries arbitrary profile metadata (e.g. avatar emoji, hue).\n */\nexport const Info = Schema.Struct({\n did: IdentityDid,\n /** Hex-encoded identity (credential) key, when known. */\n identityKey: Schema.optional(Schema.String),\n displayName: Schema.optional(Schema.String),\n /** Arbitrary profile metadata. */\n data: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),\n});\nexport type Info = typeof Info.Type;\n\n/**\n * Public view of a device belonging to the local identity. Replaces the legacy `Device` proxy\n * type (`deviceKey` → `key`).\n */\nexport const DeviceInfo = Schema.Struct({\n /** Hex-encoded device key. */\n key: Schema.String,\n kind: Schema.optional(DeviceKind),\n label: Schema.optional(Schema.String),\n /** Whether this device is the local (current) device. */\n current: Schema.Boolean,\n});\nexport type DeviceInfo = typeof DeviceInfo.Type;\n\n/**\n * Public view of a HALO credential. Replaces direct consumption of the protobuf `Credential`:\n * `type` is the subject assertion's `@type`, `id` its hex-encoded credential id.\n */\nexport const Credential = Schema.Struct({\n /** Hex-encoded credential id, when assigned. */\n id: Schema.optional(Schema.String),\n /** The subject assertion's `@type` (e.g. `dxos.halo.credentials.IdentityRecovery`). */\n type: Schema.String,\n issuanceDate: Schema.optional(Schema.DateFromSelf),\n});\nexport type Credential = typeof Credential.Type;\n\n/**\n * Options for a self-issued `ServiceAccess` credential granting the identity access to an\n * EDGE/Hub service.\n */\nexport type ServiceAccessOptions = {\n /** Target server name (e.g. `hub.dxos.network`). */\n readonly serverName: string;\n /** Capabilities to grant (e.g. `['composer:beta']`). */\n readonly capabilities: readonly string[];\n};\n\n/**\n * Recovery credential presented to re-admit a device to an existing identity.\n */\nexport type RecoverArgs =\n | { readonly recoveryCode: string }\n | { readonly token: string }\n | { readonly recoveryProof: string };\n\n/**\n * Identity and device management, plus device invitations. `share`/`join` construct\n * {@link Invitation.Flow}s driven through the {@link Invitation} flow verbs; `invitations`\n * observes the active (host-created) device-invitation flows.\n */\nexport class Service extends Context.Tag('@dxos/halo/Identity')<\n Service,\n {\n /**\n * The local identity (`Option.none` when none exists) as a stream that emits the current\n * value immediately on subscription. Take the first element for a one-shot read; subscribe\n * for updates.\n */\n readonly identity: Stream.Stream<Option.Option<Info>>;\n /**\n * Synchronous snapshot of the local identity (`Option.none` when none exists). For imperative\n * callers (non-React, non-Effect) that need the current value without subscribing.\n */\n readonly getSnapshot: () => Option.Option<Info>;\n /**\n * Subscribe to local-identity changes (imperative). Invokes `callback` immediately with the\n * current value, then on each change. Returns an unsubscribe function.\n */\n readonly subscribe: (callback: (identity: Option.Option<Info>) => void) => () => void;\n /** Create the local identity (and its first device). */\n readonly create: (options?: { displayName?: string; deviceLabel?: string }) => Effect.Effect<Info, IdentityError>;\n /** Re-admit this device to an existing identity via a recovery credential. */\n readonly recover: (args: RecoverArgs) => Effect.Effect<Info, IdentityError>;\n /** Update the identity profile. */\n readonly updateProfile: (profile: {\n displayName?: string;\n data?: Record<string, unknown>;\n }) => Effect.Effect<Info, IdentityError>;\n /** Devices belonging to the local identity; emits the current set immediately. */\n readonly devices: Stream.Stream<readonly DeviceInfo[]>;\n /** Synchronous snapshot of the local identity's devices, for imperative callers. */\n readonly getDevicesSnapshot: () => readonly DeviceInfo[];\n /** HALO credentials of the local identity; emits the current set immediately. */\n readonly credentials: Stream.Stream<readonly Credential[]>;\n /**\n * Grant this identity access to an EDGE/Hub service by writing a `ServiceAccess` credential\n * (self-issued). Replaces hand-constructing the protobuf credential at the call site.\n */\n readonly grantServiceAccess: (options: ServiceAccessOptions) => Effect.Effect<void, IdentityError>;\n /** Initiate a device invitation (host side). */\n readonly share: (options?: Invitation.ShareOptions) => Effect.Effect<Invitation.Flow, IdentityError>;\n /** Redeem a device-invitation code on a new device (guest side). */\n readonly join: (code: string) => Effect.Effect<Invitation.Flow, IdentityError>;\n /** Active (host-created) device-invitation flows; emits the current set immediately. */\n readonly invitations: Stream.Stream<readonly Invitation.Flow[]>;\n }\n>() {}\n\n/** The local identity as a current-value stream (requires {@link Service}). */\nexport const identity: Stream.Stream<Option.Option<Info>, never, Service> = Stream.unwrap(\n Effect.map(Service, (service) => service.identity),\n);\n\n/** Synchronous snapshot of the local identity (requires {@link Service}). */\nexport const getSnapshot: Effect.Effect<Option.Option<Info>, never, Service> = Effect.map(Service, (service) =>\n service.getSnapshot(),\n);\n\n/** Create the local identity (requires {@link Service}). */\nexport const create = (options?: {\n displayName?: string;\n deviceLabel?: string;\n}): Effect.Effect<Info, IdentityError, Service> => Effect.flatMap(Service, (service) => service.create(options));\n\n/** Re-admit this device via a recovery credential (requires {@link Service}). */\nexport const recover = (args: RecoverArgs): Effect.Effect<Info, IdentityError, Service> =>\n Effect.flatMap(Service, (service) => service.recover(args));\n\n/** Update the identity profile (requires {@link Service}). */\nexport const updateProfile = (profile: {\n displayName?: string;\n data?: Record<string, unknown>;\n}): Effect.Effect<Info, IdentityError, Service> => Effect.flatMap(Service, (service) => service.updateProfile(profile));\n\n/** Devices belonging to the local identity as a current-value stream (requires {@link Service}). */\nexport const devices: Stream.Stream<readonly DeviceInfo[], never, Service> = Stream.unwrap(\n Effect.map(Service, (service) => service.devices),\n);\n\n/** Synchronous snapshot of the local identity's devices (requires {@link Service}). */\nexport const getDevicesSnapshot: Effect.Effect<readonly DeviceInfo[], never, Service> = Effect.map(Service, (service) =>\n service.getDevicesSnapshot(),\n);\n\n/** HALO credentials as a current-value stream (requires {@link Service}). */\nexport const credentials: Stream.Stream<readonly Credential[], never, Service> = Stream.unwrap(\n Effect.map(Service, (service) => service.credentials),\n);\n\n/** Grant the identity access to an EDGE/Hub service (requires {@link Service}). */\nexport const grantServiceAccess = (options: ServiceAccessOptions): Effect.Effect<void, IdentityError, Service> =>\n Effect.flatMap(Service, (service) => service.grantServiceAccess(options));\n\n/** Initiate a device invitation (requires {@link Service}). */\nexport const share = (options?: Invitation.ShareOptions): Effect.Effect<Invitation.Flow, IdentityError, Service> =>\n Effect.flatMap(Service, (service) => service.share(options));\n\n/** Redeem a device-invitation code (requires {@link Service}). */\nexport const join = (code: string): Effect.Effect<Invitation.Flow, IdentityError, Service> =>\n Effect.flatMap(Service, (service) => service.join(code));\n\n/** Active device-invitation flows as a current-value stream (requires {@link Service}). */\nexport const invitations: Stream.Stream<readonly Invitation.Flow[], never, Service> = Stream.unwrap(\n Effect.map(Service, (service) => service.invitations),\n);\n", "//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Effect from 'effect/Effect';\nimport * as Stream from 'effect/Stream';\n\nimport { type IdentityDid, type SpaceId } from '@dxos/keys';\n\nimport { type InvitationError } from './errors';\n\n/**\n * Whether an invitation admits a device to an identity or a member to a space.\n */\nexport type Kind = 'device' | 'space';\n\n/**\n * How a guest proves it may redeem the invitation.\n * Mirrors the legacy `Invitation.AuthMethod` protobuf enum.\n */\nexport type AuthMethod = 'none' | 'shared-secret' | 'known-public-key';\n\n/**\n * Interactive (online host+guest handshake) vs delegated (offline-redeemable) invitation.\n * Mirrors the legacy `Invitation.Type` protobuf enum.\n */\nexport type Type = 'interactive' | 'delegated' | 'multiuse';\n\n/**\n * Options for initiating an invitation. Passed to {@link Identity.share} / {@link Space.share}.\n */\nexport type ShareOptions = {\n readonly authMethod?: AuthMethod;\n readonly type?: Type;\n readonly multiUse?: boolean;\n /** Restrict a `known-public-key` invitation to a specific guest (key/DID). */\n readonly target?: string;\n};\n\n/**\n * Outcome of a completed invitation flow.\n */\nexport type Result = {\n readonly spaceId?: SpaceId;\n readonly identityDid?: IdentityDid;\n};\n\n/**\n * A lifecycle event emitted by an invitation {@link Flow}. Terminal events are `success`,\n * `cancelled`, and `error`. Replaces polling on the legacy `Invitation.State` enum.\n */\nexport type Event =\n | { readonly _tag: 'connecting' }\n | { readonly _tag: 'connected' }\n | { readonly _tag: 'readyForAuthentication'; readonly authCode?: string }\n | { readonly _tag: 'authenticating' }\n | { readonly _tag: 'success'; readonly result: Result }\n | { readonly _tag: 'cancelled' }\n | { readonly _tag: 'error'; readonly message: string };\n\n/**\n * An in-flight invitation, host or guest side. Produced by {@link Identity.share}/`join` and\n * {@link Space.share}/`join`; its lifecycle is then driven through this handle and the\n * {@link Service}.\n */\nexport interface Flow {\n readonly id: string;\n readonly kind: Kind;\n /** Hot stream of lifecycle events; completes after a terminal event. */\n readonly events: Stream.Stream<Event>;\n /** Supply the auth code when the flow reaches `readyForAuthentication`. */\n authenticate(code: string): Effect.Effect<void, InvitationError>;\n /** Abort the flow. */\n cancel(): Effect.Effect<void>;\n /** Encoded, shareable invitation code (host side). */\n readonly code: Effect.Effect<string>;\n}\n\n/**\n * Supply the auth code to a flow awaiting authentication. Flow verbs operate on a {@link Flow}\n * handle directly and require no service; the active-flow set is queried through\n * {@link Identity} (device invitations) and {@link Space} (space invitations).\n */\nexport const authenticate = (flow: Flow, code: string): Effect.Effect<void, InvitationError> => flow.authenticate(code);\n\n/** Abort a flow. */\nexport const cancel = (flow: Flow): Effect.Effect<void> => flow.cancel();\n\n/** Lifecycle event stream of a flow. */\nexport const events = (flow: Flow): Stream.Stream<Event> => flow.events;\n\n/** Encoded, shareable code for a flow. */\nexport const code = (flow: Flow): Effect.Effect<string> => flow.code;\n", "//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\nimport * as Stream from 'effect/Stream';\n\nimport { IdentityDid, SpaceId } from '@dxos/keys';\n\nimport { type SpaceError } from './errors';\nimport * as Invitation from './Invitation';\n\n/**\n * Capability level granted to a space member, matching the Keyhive `Access` enum. Ordered; each\n * implies the previous: `pull` < `read` < `edit` < `admin`. Replaces the legacy\n * `SpaceMember.Role` enum.\n */\nexport const Access = Schema.Literal('pull', 'read', 'edit', 'admin');\nexport type Access = typeof Access.Type;\n\n/**\n * Lifecycle state of a space. Replaces the legacy `SpaceState` protobuf enum (subset relevant to\n * consumers).\n */\nexport const State = Schema.Literal('inactive', 'closed', 'ready');\nexport type State = typeof State.Type;\n\n/**\n * Who may join a space. Replaces the legacy `MembershipPolicy` protobuf enum: `invite` admits\n * members via invitation only; `locked` admits no new members.\n */\nexport const MembershipPolicy = Schema.Literal('invite', 'locked');\nexport type MembershipPolicy = typeof MembershipPolicy.Type;\n\n/**\n * Whether a space replicates through EDGE. Replaces the legacy `EdgeReplicationSetting` protobuf\n * enum.\n */\nexport const EdgeReplication = Schema.Literal('disabled', 'enabled');\nexport type EdgeReplication = typeof EdgeReplication.Type;\n\n/**\n * A space membership entry. Membership (HALO) only — liveness/presence is a separate concern\n * (see API_AUDIT.md §3.6).\n */\nexport const Member = Schema.Struct({\n /** DID of the member identity, when known. */\n did: Schema.optional(IdentityDid),\n /** Hex-encoded identity key of the member, for avatar/presence keying. */\n identityKey: Schema.optional(Schema.String),\n displayName: Schema.optional(Schema.String),\n /** Arbitrary profile metadata (e.g. avatar emoji, hue). */\n data: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Any })),\n role: Access,\n /** Whether the member is currently online. */\n online: Schema.Boolean,\n});\nexport type Member = typeof Member.Type;\n\n/**\n * Public view of a space. A plain snapshot — database access stays on the ECHO `Database`\n * service keyed by {@link SpaceId}, not on this value.\n */\nexport const Info = Schema.Struct({\n id: SpaceId,\n name: Schema.optional(Schema.String),\n state: State,\n});\nexport type Info = typeof Info.Type;\n\n/**\n * A serialized space archive (export/import payload).\n */\nexport type Archive = {\n readonly filename: string;\n readonly contents: Uint8Array;\n};\n\nexport type CreateOptions = {\n readonly name?: string;\n /** Tags applied to the new space. */\n readonly tags?: readonly string[];\n /** Who may join the space (defaults to `invite`). */\n readonly membershipPolicy?: MembershipPolicy;\n};\n\n/**\n * Space management and membership, plus space invitations. `share`/`join` construct\n * {@link Invitation.Flow}s driven through the {@link Invitation} flow verbs; `invitations`\n * observes the active (host-created) space-invitation flows.\n */\nexport class Service extends Context.Tag('@dxos/halo/Space')<\n Service,\n {\n /**\n * All spaces known to the local identity as a stream that emits the current set immediately\n * on subscription. Take the first element for a one-shot read; subscribe for updates.\n */\n readonly spaces: Stream.Stream<readonly Info[]>;\n /** Resolve a space by id. */\n readonly get: (id: SpaceId) => Effect.Effect<Option.Option<Info>>;\n /** Create a new space. */\n readonly create: (options?: CreateOptions) => Effect.Effect<Info, SpaceError>;\n /** Resolve once the space has reached the `ready` state. */\n readonly waitReady: (id: SpaceId) => Effect.Effect<void, SpaceError>;\n /** Enable or disable EDGE replication for a space. */\n readonly setEdgeReplication: (id: SpaceId, setting: EdgeReplication) => Effect.Effect<void, SpaceError>;\n /** A space's membership; emits the current set immediately, then on join/leave/role/presence. */\n readonly members: (id: SpaceId) => Stream.Stream<readonly Member[]>;\n /** Change a member's access level (Keyhive delegation). */\n readonly updateMemberRole: (id: SpaceId, subject: IdentityDid, role: Access) => Effect.Effect<void, SpaceError>;\n /** Remove a member (Keyhive revocation). */\n readonly removeMember: (id: SpaceId, subject: IdentityDid) => Effect.Effect<void, SpaceError>;\n /** Initiate a space invitation (host side). */\n readonly share: (id: SpaceId, options?: Invitation.ShareOptions) => Effect.Effect<Invitation.Flow, SpaceError>;\n /** Redeem a space-invitation code (guest side). */\n readonly join: (code: string) => Effect.Effect<Invitation.Flow, SpaceError>;\n /** A space's active (host-created) invitation flows; emits the current set immediately. */\n readonly invitations: (id: SpaceId) => Stream.Stream<readonly Invitation.Flow[]>;\n /** Export a space to an archive. */\n readonly export: (id: SpaceId) => Effect.Effect<Archive, SpaceError>;\n /** Import a space from an archive. */\n readonly import: (archive: Archive, options?: { tags?: readonly string[] }) => Effect.Effect<Info, SpaceError>;\n }\n>() {}\n\n/** All spaces as a current-value stream (requires {@link Service}). */\nexport const spaces: Stream.Stream<readonly Info[], never, Service> = Stream.unwrap(\n Effect.map(Service, (service) => service.spaces),\n);\n\n/** Resolve a space by id (requires {@link Service}). */\nexport const get = (id: SpaceId): Effect.Effect<Option.Option<Info>, never, Service> =>\n Effect.flatMap(Service, (service) => service.get(id));\n\n/** Create a new space (requires {@link Service}). */\nexport const create = (options?: CreateOptions): Effect.Effect<Info, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.create(options));\n\n/** Resolve once the space is ready (requires {@link Service}). */\nexport const waitReady = (id: SpaceId): Effect.Effect<void, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.waitReady(id));\n\n/** Enable or disable EDGE replication for a space (requires {@link Service}). */\nexport const setEdgeReplication = (id: SpaceId, setting: EdgeReplication): Effect.Effect<void, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.setEdgeReplication(id, setting));\n\n/** A space's membership as a current-value stream (requires {@link Service}). */\nexport const members = (id: SpaceId): Stream.Stream<readonly Member[], never, Service> =>\n Stream.unwrap(Effect.map(Service, (service) => service.members(id)));\n\n/** Change a member's access level (requires {@link Service}). */\nexport const updateMemberRole = (\n id: SpaceId,\n subject: IdentityDid,\n role: Access,\n): Effect.Effect<void, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.updateMemberRole(id, subject, role));\n\n/** Remove a member (requires {@link Service}). */\nexport const removeMember = (id: SpaceId, subject: IdentityDid): Effect.Effect<void, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.removeMember(id, subject));\n\n/** Initiate a space invitation (requires {@link Service}). */\nexport const share = (\n id: SpaceId,\n options?: Invitation.ShareOptions,\n): Effect.Effect<Invitation.Flow, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.share(id, options));\n\n/** Redeem a space-invitation code (requires {@link Service}). */\nexport const join = (code: string): Effect.Effect<Invitation.Flow, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.join(code));\n\n/** A space's active invitation flows as a current-value stream (requires {@link Service}). */\nexport const invitations = (id: SpaceId): Stream.Stream<readonly Invitation.Flow[], never, Service> =>\n Stream.unwrap(Effect.map(Service, (service) => service.invitations(id)));\n\n/** Export a space to an archive (requires {@link Service}). */\nexport const exportSpace = (id: SpaceId): Effect.Effect<Archive, SpaceError, Service> =>\n Effect.flatMap(Service, (service) => service.export(id));\n\n/** Import a space from an archive (requires {@link Service}). */\nexport const importSpace = (\n archive: Archive,\n options?: { tags?: readonly string[] },\n): Effect.Effect<Info, SpaceError, Service> => Effect.flatMap(Service, (service) => service.import(archive, options));\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { BaseError } from '@dxos/errors';\n\n/**\n * The acting principal lacks the capability required for the operation\n * (e.g. delegating access above their own level, or revoking without causal seniority).\n */\nexport class NotAuthorizedError extends BaseError.extend('NotAuthorizedError', 'Not authorized') {}\n\n/**\n * The referenced principal (individual or group) is not known to the service.\n */\nexport class UnknownPrincipalError extends BaseError.extend('UnknownPrincipalError', 'Unknown principal') {}\n\n/**\n * A signed payload failed signature verification or its id does not match its key.\n */\nexport class InvalidSignatureError extends BaseError.extend('InvalidSignatureError', 'Invalid signature') {}\n\n/**\n * A membership operation references causal predecessors that have not been received.\n */\nexport class MissingDependencyError extends BaseError.extend('MissingDependencyError', 'Missing dependency') {}\n\n/**\n * An identity/device operation (create, recover, profile/device update, device invitation) failed.\n */\nexport class IdentityError extends BaseError.extend('IdentityError', 'Identity operation failed') {}\n\n/**\n * A space operation (create, query, membership, invitation, export/import) failed.\n */\nexport class SpaceError extends BaseError.extend('SpaceError', 'Space operation failed') {}\n\n/**\n * An invitation-lifecycle operation (authenticate, cancel) failed.\n */\nexport class InvitationError extends BaseError.extend('InvitationError', 'Invitation operation failed') {}\n"],
5
- "mappings": "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",
6
- "names": ["Context", "Effect", "Schema", "Stream", "IdentityDid", "DeviceKind", "Literal", "Info", "Struct", "did", "identityKey", "optional", "String", "displayName", "data", "Record", "key", "value", "Any", "DeviceInfo", "kind", "label", "current", "Boolean", "Credential", "id", "type", "issuanceDate", "DateFromSelf", "Service", "Tag", "identity", "unwrap", "map", "service", "getSnapshot", "create", "options", "flatMap", "recover", "args", "updateProfile", "profile", "devices", "getDevicesSnapshot", "credentials", "grantServiceAccess", "share", "join", "code", "invitations", "authenticate", "flow", "code", "cancel", "events", "Info", "Service", "create", "invitations", "join", "share", "Context", "Effect", "Schema", "Stream", "IdentityDid", "SpaceId", "Access", "Literal", "State", "MembershipPolicy", "EdgeReplication", "Member", "Struct", "did", "optional", "identityKey", "String", "displayName", "data", "Record", "key", "value", "Any", "role", "online", "Boolean", "id", "name", "state", "Tag", "spaces", "unwrap", "map", "service", "get", "flatMap", "options", "waitReady", "setEdgeReplication", "setting", "members", "updateMemberRole", "subject", "removeMember", "code", "exportSpace", "export", "importSpace", "archive", "import", "BaseError", "NotAuthorizedError", "extend", "UnknownPrincipalError", "InvalidSignatureError", "MissingDependencyError", "IdentityError", "SpaceError", "InvitationError"]
7
- }
@@ -1 +0,0 @@
1
- {"inputs":{"src/Identity.ts":{"bytes":20329,"imports":[{"path":"effect/Context","kind":"import-statement","external":true},{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"effect/Stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true}],"format":"esm"},"src/Invitation.ts":{"bytes":5705,"imports":[],"format":"esm"},"src/Space.ts":{"bytes":20439,"imports":[{"path":"effect/Context","kind":"import-statement","external":true},{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"effect/Stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true}],"format":"esm"},"src/errors.ts":{"bytes":4689,"imports":[{"path":"@dxos/errors","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":824,"imports":[{"path":"src/Identity.ts","kind":"import-statement","original":"./Identity"},{"path":"src/Invitation.ts","kind":"import-statement","original":"./Invitation"},{"path":"src/Space.ts","kind":"import-statement","original":"./Space"},{"path":"src/errors.ts","kind":"import-statement","original":"./errors"}],"format":"esm"}},"outputs":{"dist/lib/neutral/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":28089},"dist/lib/neutral/index.mjs":{"imports":[{"path":"effect/Context","kind":"import-statement","external":true},{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"effect/Stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"effect/Context","kind":"import-statement","external":true},{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"effect/Stream","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@dxos/errors","kind":"import-statement","external":true}],"exports":["Identity","IdentityError","InvalidSignatureError","Invitation","InvitationError","MissingDependencyError","NotAuthorizedError","Space","SpaceError","UnknownPrincipalError"],"entryPoint":"src/index.ts","inputs":{"src/Identity.ts":{"bytesInOutput":2904},"src/index.ts":{"bytesInOutput":0},"src/Invitation.ts":{"bytesInOutput":335},"src/Space.ts":{"bytesInOutput":3139},"src/errors.ts":{"bytesInOutput":779}},"bytes":7722}}}