@open-pets/client 0.1.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.
@@ -0,0 +1,62 @@
1
+ import { type LeaseResult, type OpenPetsLeaseClient, type OpenPetsState } from "@open-pets/core";
2
+ import { type OpenPetsHealthV2, type OpenPetsWindowAction } from "@open-pets/core/ipc";
3
+ import { OpenPetsClientError } from "./errors.js";
4
+ import { type OpenPetsEventInput } from "./event-input.js";
5
+ export type OpenPetsClientOptions = {
6
+ endpoint?: string;
7
+ timeoutMs?: number;
8
+ verifyOpenPets?: boolean;
9
+ };
10
+ export type OpenPetsHealth = OpenPetsHealthV2;
11
+ export type OpenPetsSafeResult = {
12
+ ok: true;
13
+ state?: OpenPetsState;
14
+ } | {
15
+ ok: false;
16
+ error: OpenPetsClientError;
17
+ };
18
+ export type OpenPetsLeaseInput = {
19
+ id: string;
20
+ client: OpenPetsLeaseClient;
21
+ label?: string;
22
+ ttlMs?: number;
23
+ autoClose?: boolean;
24
+ };
25
+ export type OpenPetsClient = {
26
+ getHealth(options?: OpenPetsClientOptions): Promise<OpenPetsHealth>;
27
+ isRunning(options?: OpenPetsClientOptions): Promise<boolean>;
28
+ sendEvent(event: OpenPetsEventInput, options?: OpenPetsClientOptions): Promise<{
29
+ ok: true;
30
+ state: OpenPetsState;
31
+ }>;
32
+ safeSendEvent(event: OpenPetsEventInput, options?: OpenPetsClientOptions): Promise<OpenPetsSafeResult>;
33
+ windowAction(action: OpenPetsWindowAction, options?: OpenPetsClientOptions): Promise<{
34
+ ok: true;
35
+ action: OpenPetsWindowAction;
36
+ }>;
37
+ leaseAcquire(input: OpenPetsLeaseInput, options?: OpenPetsClientOptions): Promise<LeaseResult>;
38
+ leaseHeartbeat(input: {
39
+ id: string;
40
+ ttlMs?: number;
41
+ }, options?: OpenPetsClientOptions): Promise<LeaseResult>;
42
+ leaseRelease(id: string, options?: OpenPetsClientOptions): Promise<LeaseResult>;
43
+ };
44
+ export declare function createOpenPetsClient(options?: OpenPetsClientOptions): OpenPetsClient;
45
+ export declare function getHealth(options?: OpenPetsClientOptions): Promise<OpenPetsHealthV2>;
46
+ export declare function isOpenPetsRunning(options?: OpenPetsClientOptions): Promise<boolean>;
47
+ export declare function sendEvent(event: OpenPetsEventInput, options?: OpenPetsClientOptions): Promise<{
48
+ ok: true;
49
+ state: OpenPetsState;
50
+ }>;
51
+ export declare function safeSendEvent(event: OpenPetsEventInput, options?: OpenPetsClientOptions): Promise<OpenPetsSafeResult>;
52
+ export declare function windowAction(action: OpenPetsWindowAction, options?: OpenPetsClientOptions): Promise<{
53
+ ok: true;
54
+ action: OpenPetsWindowAction;
55
+ }>;
56
+ export declare function leaseAcquire(input: OpenPetsLeaseInput, options?: OpenPetsClientOptions): Promise<LeaseResult>;
57
+ export declare function leaseHeartbeat(input: {
58
+ id: string;
59
+ ttlMs?: number;
60
+ }, options?: OpenPetsClientOptions): Promise<LeaseResult>;
61
+ export declare function leaseRelease(id: string, options?: OpenPetsClientOptions): Promise<LeaseResult>;
62
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,258 @@
1
+ import { createConnection } from "node:net";
2
+ import { isOpenPetsState } from "@open-pets/core";
3
+ import { getDefaultOpenPetsIpcEndpoint, isOpenPetsWindowAction, MAX_IPC_FRAME_BYTES, OPENPETS_IPC_PROTOCOL_VERSION, parseIpcFrame, serializeIpcRequest, } from "@open-pets/core/ipc";
4
+ import { OpenPetsClientError } from "./errors.js";
5
+ import { normalizeEventInput } from "./event-input.js";
6
+ export function createOpenPetsClient(options = {}) {
7
+ let verifiedEndpoint = null;
8
+ function mergedOptions(overrides = {}) {
9
+ return {
10
+ endpoint: overrides.endpoint ?? options.endpoint ?? getDefaultOpenPetsIpcEndpoint(),
11
+ timeoutMs: overrides.timeoutMs ?? options.timeoutMs,
12
+ verifyOpenPets: overrides.verifyOpenPets ?? options.verifyOpenPets ?? true,
13
+ };
14
+ }
15
+ async function getHealthForClient(overrides = {}) {
16
+ const merged = mergedOptions(overrides);
17
+ return fetchHealth(merged.endpoint, merged.timeoutMs ?? 1000);
18
+ }
19
+ async function sendEventForClient(event, overrides = {}) {
20
+ const merged = mergedOptions(overrides);
21
+ const timeoutMs = merged.timeoutMs ?? 1000;
22
+ const deadline = Date.now() + timeoutMs;
23
+ if (merged.verifyOpenPets && verifiedEndpoint !== merged.endpoint) {
24
+ await fetchHealth(merged.endpoint, remainingMs(deadline));
25
+ verifiedEndpoint = merged.endpoint;
26
+ }
27
+ return sendEventIpc(merged.endpoint, normalizeEventInput(event), remainingMs(deadline));
28
+ }
29
+ async function safeSendEventForClient(event, overrides = {}) {
30
+ try {
31
+ return await sendEventForClient(event, { ...overrides, timeoutMs: overrides.timeoutMs ?? options.timeoutMs ?? 400 });
32
+ }
33
+ catch (error) {
34
+ return { ok: false, error: toClientError(error) };
35
+ }
36
+ }
37
+ async function windowActionForClient(action, overrides = {}) {
38
+ if (!isOpenPetsWindowAction(action))
39
+ throw new OpenPetsClientError("rejected", "Invalid OpenPets window action");
40
+ const merged = mergedOptions(overrides);
41
+ const response = await requestIpc(merged.endpoint, { id: createRequestId("window"), method: "window", params: { action } }, merged.timeoutMs ?? 1000);
42
+ return validateWindowActionResult(unwrapIpcResult(response));
43
+ }
44
+ async function leaseRequestForClient(params, overrides = {}) {
45
+ const merged = mergedOptions(overrides);
46
+ const response = await requestIpc(merged.endpoint, { id: createRequestId("lease"), method: "lease", params }, merged.timeoutMs ?? 1000);
47
+ return validateLeaseResult(unwrapIpcResult(response));
48
+ }
49
+ return {
50
+ getHealth: getHealthForClient,
51
+ async isRunning(overrides) {
52
+ try {
53
+ await getHealthForClient(overrides);
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ },
60
+ sendEvent: sendEventForClient,
61
+ safeSendEvent: safeSendEventForClient,
62
+ windowAction: windowActionForClient,
63
+ leaseAcquire(input, overrides) {
64
+ return leaseRequestForClient({ action: "acquire", ...input }, overrides);
65
+ },
66
+ leaseHeartbeat(input, overrides) {
67
+ return leaseRequestForClient({ action: "heartbeat", ...input }, overrides);
68
+ },
69
+ leaseRelease(id, overrides) {
70
+ return leaseRequestForClient({ action: "release", id }, overrides);
71
+ },
72
+ };
73
+ }
74
+ const defaultClient = createOpenPetsClient();
75
+ export function getHealth(options) {
76
+ return defaultClient.getHealth(options);
77
+ }
78
+ export function isOpenPetsRunning(options) {
79
+ return defaultClient.isRunning(options);
80
+ }
81
+ export function sendEvent(event, options) {
82
+ return defaultClient.sendEvent(event, options);
83
+ }
84
+ export function safeSendEvent(event, options) {
85
+ return defaultClient.safeSendEvent(event, options);
86
+ }
87
+ export function windowAction(action, options) {
88
+ return defaultClient.windowAction(action, options);
89
+ }
90
+ export function leaseAcquire(input, options) {
91
+ return defaultClient.leaseAcquire(input, options);
92
+ }
93
+ export function leaseHeartbeat(input, options) {
94
+ return defaultClient.leaseHeartbeat(input, options);
95
+ }
96
+ export function leaseRelease(id, options) {
97
+ return defaultClient.leaseRelease(id, options);
98
+ }
99
+ async function fetchHealth(endpoint, timeoutMs) {
100
+ const response = await requestIpc(endpoint, { id: createRequestId("health"), method: "health" }, timeoutMs);
101
+ return validateIpcHealth(unwrapIpcResult(response));
102
+ }
103
+ async function sendEventIpc(endpoint, event, timeoutMs) {
104
+ const response = await requestIpc(endpoint, { id: createRequestId("event"), method: "event", params: event }, timeoutMs);
105
+ return validateEventResult(unwrapIpcResult(response));
106
+ }
107
+ function requestIpc(endpoint, request, timeoutMs) {
108
+ return new Promise((resolve, reject) => {
109
+ let settled = false;
110
+ let buffer = Buffer.alloc(0);
111
+ const socket = createConnection(endpoint);
112
+ const timeout = setTimeout(() => settle(reject, new OpenPetsClientError("timeout", "OpenPets request timed out")), timeoutMs);
113
+ socket.on("connect", () => {
114
+ try {
115
+ socket.write(serializeIpcRequest(request));
116
+ }
117
+ catch (error) {
118
+ settle(reject, error);
119
+ }
120
+ });
121
+ socket.on("data", (chunk) => {
122
+ buffer = Buffer.concat([buffer, typeof chunk === "string" ? Buffer.from(chunk) : chunk]);
123
+ if (buffer.byteLength > MAX_IPC_FRAME_BYTES) {
124
+ settle(reject, new OpenPetsClientError("invalid-response", "OpenPets IPC response is too large"));
125
+ return;
126
+ }
127
+ const newlineIndex = buffer.indexOf(0x0a);
128
+ if (newlineIndex < 0)
129
+ return;
130
+ try {
131
+ settle(resolve, validateIpcResponse(parseIpcFrame(buffer.subarray(0, newlineIndex + 1)), request.id));
132
+ }
133
+ catch (error) {
134
+ settle(reject, error);
135
+ }
136
+ });
137
+ socket.on("end", () => {
138
+ if (!settled)
139
+ settle(reject, new OpenPetsClientError("invalid-response", "OpenPets IPC response ended before a complete frame"));
140
+ });
141
+ socket.on("close", () => {
142
+ if (!settled)
143
+ settle(reject, new OpenPetsClientError("not-running", "OpenPets is not running or cannot be reached"));
144
+ });
145
+ socket.on("error", (error) => {
146
+ settle(reject, error.code === "ENOENT" || error.code === "ECONNREFUSED"
147
+ ? new OpenPetsClientError("not-running", "OpenPets is not running or cannot be reached", { cause: error })
148
+ : toClientError(error));
149
+ });
150
+ function settle(fn, value) {
151
+ if (settled)
152
+ return;
153
+ settled = true;
154
+ clearTimeout(timeout);
155
+ socket.destroy();
156
+ fn(value);
157
+ }
158
+ });
159
+ }
160
+ function validateIpcResponse(input, expectedId) {
161
+ if (!input || typeof input !== "object" || Array.isArray(input))
162
+ throw new OpenPetsClientError("invalid-response", "OpenPets IPC response must be an object");
163
+ const record = input;
164
+ if (typeof record.id !== "string" || typeof record.ok !== "boolean")
165
+ throw new OpenPetsClientError("invalid-response", "OpenPets IPC response is missing required fields");
166
+ if (record.id !== expectedId)
167
+ throw new OpenPetsClientError("invalid-response", "OpenPets IPC response id did not match request id");
168
+ if (record.ok)
169
+ return { id: record.id, ok: true, result: record.result };
170
+ const error = record.error;
171
+ if (!error || typeof error !== "object" || Array.isArray(error))
172
+ throw new OpenPetsClientError("invalid-response", "OpenPets IPC error response is invalid");
173
+ const code = error.code;
174
+ const message = error.message;
175
+ return { id: record.id, ok: false, error: { code: typeof code === "string" ? code : "internal-error", message: typeof message === "string" ? message : "OpenPets IPC request failed" } };
176
+ }
177
+ function unwrapIpcResult(response) {
178
+ if (response.ok)
179
+ return response.result;
180
+ if (response.error.code === "timeout")
181
+ throw new OpenPetsClientError("timeout", response.error.message);
182
+ if (response.error.code === "invalid-params")
183
+ throw new OpenPetsClientError("rejected", response.error.message);
184
+ throw new OpenPetsClientError("invalid-response", response.error.message);
185
+ }
186
+ function validateIpcHealth(input) {
187
+ if (!input || typeof input !== "object" || Array.isArray(input))
188
+ throw new OpenPetsClientError("invalid-response", "OpenPets IPC health response must be an object");
189
+ const record = input;
190
+ if (record.app !== "openpets")
191
+ throw new OpenPetsClientError("not-openpets", "IPC endpoint is not served by OpenPets");
192
+ if (record.protocolVersion !== OPENPETS_IPC_PROTOCOL_VERSION || record.transport !== "ipc")
193
+ throw new OpenPetsClientError("incompatible-protocol", "OpenPets IPC protocol version is not supported");
194
+ if (record.ok !== true || typeof record.version !== "string" || typeof record.ready !== "boolean")
195
+ throw new OpenPetsClientError("invalid-response", "OpenPets IPC health response is missing required fields");
196
+ return {
197
+ app: "openpets",
198
+ ok: true,
199
+ version: record.version,
200
+ protocolVersion: OPENPETS_IPC_PROTOCOL_VERSION,
201
+ transport: "ipc",
202
+ capabilities: Array.isArray(record.capabilities) ? record.capabilities.filter((item) => item === "event-v2" || item === "window-v1" || item === "speech-v1" || item === "lease-v1") : [],
203
+ ready: record.ready,
204
+ activePet: typeof record.activePet === "string" ? record.activePet : null,
205
+ activeLeases: typeof record.activeLeases === "number" && Number.isFinite(record.activeLeases) ? record.activeLeases : 0,
206
+ managed: typeof record.managed === "boolean" ? record.managed : false,
207
+ ...(typeof record.debug === "boolean" ? { debug: record.debug } : {}),
208
+ ...(record.window !== undefined ? { window: record.window } : {}),
209
+ };
210
+ }
211
+ function validateEventResult(input) {
212
+ if (!input || typeof input !== "object" || Array.isArray(input))
213
+ throw new OpenPetsClientError("invalid-response", "OpenPets event response must be an object");
214
+ const record = input;
215
+ if (!isOpenPetsState(record.state))
216
+ throw new OpenPetsClientError("invalid-response", "OpenPets event response is missing state");
217
+ return { ok: true, state: record.state };
218
+ }
219
+ function validateWindowActionResult(input) {
220
+ if (!input || typeof input !== "object" || Array.isArray(input))
221
+ throw new OpenPetsClientError("invalid-response", "OpenPets window response must be an object");
222
+ const record = input;
223
+ if (!isOpenPetsWindowAction(record.action))
224
+ throw new OpenPetsClientError("invalid-response", "OpenPets window response is missing action");
225
+ return { ok: true, action: record.action };
226
+ }
227
+ function validateLeaseResult(input) {
228
+ if (!input || typeof input !== "object" || Array.isArray(input))
229
+ throw new OpenPetsClientError("invalid-response", "OpenPets lease response must be an object");
230
+ const record = input;
231
+ if (record.action !== "acquire" && record.action !== "heartbeat" && record.action !== "release")
232
+ throw new OpenPetsClientError("invalid-response", "OpenPets lease response is missing action");
233
+ if (typeof record.activeLeases !== "number" || !Number.isInteger(record.activeLeases) || record.activeLeases < 0)
234
+ throw new OpenPetsClientError("invalid-response", "OpenPets lease response is missing activeLeases");
235
+ if (typeof record.managed !== "boolean" || typeof record.leaseActive !== "boolean" || typeof record.changed !== "boolean")
236
+ throw new OpenPetsClientError("invalid-response", "OpenPets lease response is missing required fields");
237
+ return {
238
+ action: record.action,
239
+ activeLeases: record.activeLeases,
240
+ managed: record.managed,
241
+ leaseActive: record.leaseActive,
242
+ changed: record.changed,
243
+ };
244
+ }
245
+ function remainingMs(deadline) {
246
+ return Math.max(1, deadline - Date.now());
247
+ }
248
+ function createRequestId(prefix) {
249
+ return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
250
+ }
251
+ function toClientError(error) {
252
+ if (error instanceof OpenPetsClientError)
253
+ return error;
254
+ if (error && typeof error === "object" && "code" in error && (error.code === "ENOENT" || error.code === "ECONNREFUSED"))
255
+ return new OpenPetsClientError("not-running", "OpenPets is not running or cannot be reached", { cause: error });
256
+ return new OpenPetsClientError("network-error", "OpenPets request failed", { cause: error });
257
+ }
258
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export type OpenPetsClientErrorCode = "not-running" | "timeout" | "not-openpets" | "invalid-response" | "incompatible-protocol" | "rejected" | "network-error";
2
+ export declare class OpenPetsClientError extends Error {
3
+ readonly code: OpenPetsClientErrorCode;
4
+ readonly status: number | undefined;
5
+ constructor(code: OpenPetsClientErrorCode, message: string, options?: {
6
+ status?: number;
7
+ cause?: unknown;
8
+ });
9
+ }
10
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAC/B,aAAa,GACb,SAAS,GACT,cAAc,GACd,kBAAkB,GAClB,uBAAuB,GACvB,UAAU,GACV,eAAe,CAAC;AAEpB,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBAExB,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAM/G"}
package/dist/errors.js ADDED
@@ -0,0 +1,11 @@
1
+ export class OpenPetsClientError extends Error {
2
+ code;
3
+ status;
4
+ constructor(code, message, options = {}) {
5
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
6
+ this.name = "OpenPetsClientError";
7
+ this.code = code;
8
+ this.status = options.status;
9
+ }
10
+ }
11
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,CAA0B;IAC9B,MAAM,CAAqB;IAEpC,YAAY,IAA6B,EAAE,OAAe,EAAE,UAAgD,EAAE;QAC5G,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import { type OpenPetsEvent, type OpenPetsState } from "@open-pets/core";
2
+ export type OpenPetsEventInput = OpenPetsEvent | {
3
+ state: OpenPetsState;
4
+ source?: string;
5
+ type?: string;
6
+ message?: string;
7
+ tool?: string;
8
+ };
9
+ export declare function normalizeEventInput(input: OpenPetsEventInput): OpenPetsEvent;
10
+ //# sourceMappingURL=event-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-input.d.ts","sourceRoot":"","sources":["../src/event-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,kBAAkB,GAC1B,aAAa,GACb;IACE,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CAiB5E"}
@@ -0,0 +1,21 @@
1
+ import { createManualEvent, isOpenPetsState, validateOpenPetsEvent, } from "@open-pets/core";
2
+ import { OpenPetsClientError } from "./errors.js";
3
+ export function normalizeEventInput(input) {
4
+ const existing = validateOpenPetsEvent(input);
5
+ if (existing.ok)
6
+ return existing.event;
7
+ if (!input || typeof input !== "object" || Array.isArray(input) || !isOpenPetsState(input.state)) {
8
+ throw new OpenPetsClientError("rejected", existing.error);
9
+ }
10
+ const event = createManualEvent(input.state, {
11
+ source: input.source ?? "client",
12
+ type: input.type ?? `state.${input.state}`,
13
+ ...(input.message ? { message: input.message } : {}),
14
+ ...(input.tool ? { tool: input.tool } : {}),
15
+ });
16
+ const validation = validateOpenPetsEvent(event);
17
+ if (!validation.ok)
18
+ throw new OpenPetsClientError("rejected", validation.error);
19
+ return validation.event;
20
+ }
21
+ //# sourceMappingURL=event-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-input.js","sourceRoot":"","sources":["../src/event-input.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,qBAAqB,GAGtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAYlD,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAC3D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,QAAQ,CAAC,EAAE;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC;IAEvC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACjG,MAAM,IAAI,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE;QAC3C,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,QAAQ;QAChC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,SAAS,KAAK,CAAC,KAAK,EAAE;QAC1C,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,MAAM,IAAI,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAChF,OAAO,UAAU,CAAC,KAAK,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type { OpenPetsClient, OpenPetsClientOptions, OpenPetsHealth, OpenPetsLeaseInput, OpenPetsSafeResult, } from "./client.js";
2
+ export { createOpenPetsClient, getHealth, isOpenPetsRunning, leaseAcquire, leaseHeartbeat, leaseRelease, safeSendEvent, sendEvent, windowAction, } from "./client.js";
3
+ export type { OpenPetsEventInput } from "./event-input.js";
4
+ export { OpenPetsClientError } from "./errors.js";
5
+ export type { OpenPetsClientErrorCode } from "./errors.js";
6
+ export type { LeaseResult, OpenPetsEvent, OpenPetsLeaseClient, OpenPetsState } from "@open-pets/core";
7
+ export type { OpenPetsWindowAction } from "@open-pets/core/ipc";
8
+ export { createManualEvent, isOpenPetsState, validateOpenPetsEvent } from "@open-pets/core";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACT,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACtG,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { createOpenPetsClient, getHealth, isOpenPetsRunning, leaseAcquire, leaseHeartbeat, leaseRelease, safeSendEvent, sendEvent, windowAction, } from "./client.js";
2
+ export { OpenPetsClientError } from "./errors.js";
3
+ export { createManualEvent, isOpenPetsState, validateOpenPetsEvent } from "@open-pets/core";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,oBAAoB,EACpB,SAAS,EACT,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACT,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIlD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@open-pets/client",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript IPC client for OpenPets desktop.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": ["dist"],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "dependencies": {
18
+ "@open-pets/core": "0.1.0"
19
+ },
20
+ "scripts": {
21
+ "build": "bunx tsc -p tsconfig.json",
22
+ "typecheck": "bunx tsc -p tsconfig.json --noEmit",
23
+ "test": "bun test"
24
+ },
25
+ "devDependencies": {
26
+ "@types/bun": "latest",
27
+ "typescript": "^5.9.3"
28
+ }
29
+ }