spectrum-ts 0.0.1 → 0.1.2
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/dist/chunk-3TBRO2J7.js +58 -0
- package/dist/chunk-UZ2CXPOD.js +175 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +348 -0
- package/dist/providers/imessage/index.d.ts +82 -0
- package/dist/providers/imessage/index.js +418 -0
- package/dist/providers/terminal/index.d.ts +35 -0
- package/dist/providers/terminal/index.js +61 -0
- package/dist/stream-DGy4geUK.d.ts +8 -0
- package/dist/types-eXHZpal1.d.ts +261 -0
- package/package.json +48 -3
- package/src/index.ts +26 -0
- package/src/platform/define.ts +309 -0
- package/src/platform/types.ts +438 -0
- package/src/providers/imessage/auth.ts +161 -0
- package/src/providers/imessage/index.ts +153 -0
- package/src/providers/imessage/local.ts +55 -0
- package/src/providers/imessage/remote.ts +157 -0
- package/src/providers/imessage/types.ts +31 -0
- package/src/providers/terminal/index.ts +66 -0
- package/src/spectrum.ts +390 -0
- package/src/types/content.ts +85 -0
- package/src/types/message.ts +18 -0
- package/src/types/space.ts +10 -0
- package/src/types/user.ts +4 -0
- package/src/utils/cloud.ts +1 -0
- package/src/utils/stream.ts +71 -0
- package/index.js +0 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/utils/stream.ts
|
|
2
|
+
import { Repeater } from "@repeaterjs/repeater";
|
|
3
|
+
function stream(setup) {
|
|
4
|
+
const repeater = new Repeater(async (push, stop) => {
|
|
5
|
+
const emit = (value) => {
|
|
6
|
+
Promise.resolve(push(value)).catch((error) => {
|
|
7
|
+
stop(error);
|
|
8
|
+
return void 0;
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const end = (error) => {
|
|
12
|
+
stop(error);
|
|
13
|
+
};
|
|
14
|
+
const cleanup = await setup(emit, end);
|
|
15
|
+
try {
|
|
16
|
+
await stop;
|
|
17
|
+
} finally {
|
|
18
|
+
await cleanup?.();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return Object.assign(repeater, {
|
|
22
|
+
close: async () => {
|
|
23
|
+
await repeater.return(void 0);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function mergeStreams(streams) {
|
|
28
|
+
return stream((emit, end) => {
|
|
29
|
+
if (streams.length === 0) {
|
|
30
|
+
end();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let openStreams = streams.length;
|
|
34
|
+
const workers = streams.map(async (source) => {
|
|
35
|
+
try {
|
|
36
|
+
for await (const value of source) {
|
|
37
|
+
emit(value);
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
end(error);
|
|
41
|
+
} finally {
|
|
42
|
+
openStreams -= 1;
|
|
43
|
+
if (openStreams === 0) {
|
|
44
|
+
end();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return async () => {
|
|
49
|
+
await Promise.allSettled(streams.map((source) => source.close()));
|
|
50
|
+
await Promise.allSettled(workers);
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
stream,
|
|
57
|
+
mergeStreams
|
|
58
|
+
};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// src/platform/define.ts
|
|
2
|
+
function createPlatformInstance(def, runtime) {
|
|
3
|
+
const isPlatformUser = (value) => {
|
|
4
|
+
return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
5
|
+
};
|
|
6
|
+
const normalizeSpaceArgs = (args) => {
|
|
7
|
+
if (args.length === 0) {
|
|
8
|
+
return { users: [], params: void 0 };
|
|
9
|
+
}
|
|
10
|
+
const [first, ...rest] = args;
|
|
11
|
+
if (Array.isArray(first)) {
|
|
12
|
+
return {
|
|
13
|
+
users: first,
|
|
14
|
+
params: rest[0]
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (!isPlatformUser(first)) {
|
|
18
|
+
return {
|
|
19
|
+
users: [],
|
|
20
|
+
params: first
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const last = args.at(-1);
|
|
24
|
+
if (last !== void 0 && !isPlatformUser(last)) {
|
|
25
|
+
return {
|
|
26
|
+
users: args.slice(0, -1),
|
|
27
|
+
params: last
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
users: args,
|
|
32
|
+
params: void 0
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const base = {
|
|
36
|
+
async user(userID) {
|
|
37
|
+
const resolved = await def.user.resolve({
|
|
38
|
+
input: { userID },
|
|
39
|
+
client: runtime.client,
|
|
40
|
+
config: runtime.config
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
...resolved,
|
|
44
|
+
__platform: def.name
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
async space(...args) {
|
|
48
|
+
const { users, params } = normalizeSpaceArgs(args);
|
|
49
|
+
let parsedParams = params;
|
|
50
|
+
if (params !== void 0 && def.space.params) {
|
|
51
|
+
parsedParams = def.space.params.parse(params);
|
|
52
|
+
}
|
|
53
|
+
const resolved = await def.space.resolve({
|
|
54
|
+
input: { users, params: parsedParams },
|
|
55
|
+
client: runtime.client,
|
|
56
|
+
config: runtime.config
|
|
57
|
+
});
|
|
58
|
+
const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
|
|
59
|
+
const spaceRef = {
|
|
60
|
+
id: parsedSpace.id,
|
|
61
|
+
__platform: def.name
|
|
62
|
+
};
|
|
63
|
+
const typingCtx = {
|
|
64
|
+
space: spaceRef,
|
|
65
|
+
client: runtime.client,
|
|
66
|
+
config: runtime.config
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
...parsedSpace,
|
|
70
|
+
...spaceRef,
|
|
71
|
+
send: async (...content) => {
|
|
72
|
+
const built = await Promise.all(content.map((c) => c.build()));
|
|
73
|
+
await def.actions.send({
|
|
74
|
+
...typingCtx,
|
|
75
|
+
content: built
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
startTyping: async () => {
|
|
79
|
+
await def.actions.startTyping?.(typingCtx);
|
|
80
|
+
},
|
|
81
|
+
stopTyping: async () => {
|
|
82
|
+
await def.actions.stopTyping?.(typingCtx);
|
|
83
|
+
},
|
|
84
|
+
responding: async (fn) => {
|
|
85
|
+
await def.actions.startTyping?.(typingCtx);
|
|
86
|
+
try {
|
|
87
|
+
return await fn();
|
|
88
|
+
} finally {
|
|
89
|
+
await def.actions.stopTyping?.(typingCtx).catch(() => {
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const eventProperties = {};
|
|
97
|
+
for (const eventName of Object.keys(def.events)) {
|
|
98
|
+
if (eventName === "messages") {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const producer = def.events[eventName];
|
|
102
|
+
if (producer) {
|
|
103
|
+
eventProperties[eventName] = producer({
|
|
104
|
+
client: runtime.client,
|
|
105
|
+
config: runtime.config
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return Object.assign(base, eventProperties);
|
|
110
|
+
}
|
|
111
|
+
function definePlatform(name, def) {
|
|
112
|
+
const fullDef = { name, ...def };
|
|
113
|
+
const platformCache = /* @__PURE__ */ new WeakMap();
|
|
114
|
+
const narrowSpectrum = (spectrum) => {
|
|
115
|
+
const cached = platformCache.get(spectrum);
|
|
116
|
+
if (cached) {
|
|
117
|
+
return cached;
|
|
118
|
+
}
|
|
119
|
+
const runtime = spectrum.__internal.platforms.get(name);
|
|
120
|
+
if (!runtime) {
|
|
121
|
+
throw new Error(`Platform "${name}" is not registered`);
|
|
122
|
+
}
|
|
123
|
+
const instance = createPlatformInstance(
|
|
124
|
+
fullDef,
|
|
125
|
+
runtime
|
|
126
|
+
);
|
|
127
|
+
platformCache.set(spectrum, instance);
|
|
128
|
+
return instance;
|
|
129
|
+
};
|
|
130
|
+
const narrowSpace = (input) => {
|
|
131
|
+
if (input.__platform !== name) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`Expected space from "${name}", got "${input.__platform}"`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
return input;
|
|
137
|
+
};
|
|
138
|
+
const narrowMessage = (input) => {
|
|
139
|
+
if (input.platform !== name) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Expected message from "${name}", got "${input.platform}"`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return input;
|
|
145
|
+
};
|
|
146
|
+
const narrower = ((input) => {
|
|
147
|
+
if ("__providers" in input && "__internal" in input) {
|
|
148
|
+
return narrowSpectrum(input);
|
|
149
|
+
}
|
|
150
|
+
if ("__platform" in input && "send" in input) {
|
|
151
|
+
return narrowSpace(input);
|
|
152
|
+
}
|
|
153
|
+
if ("platform" in input && "sender" in input && "space" in input) {
|
|
154
|
+
return narrowMessage(input);
|
|
155
|
+
}
|
|
156
|
+
throw new Error("Invalid input to platform narrowing function");
|
|
157
|
+
});
|
|
158
|
+
narrower.config = (config = {}) => {
|
|
159
|
+
return {
|
|
160
|
+
__tag: "PlatformProviderConfig",
|
|
161
|
+
__def: void 0,
|
|
162
|
+
__name: name,
|
|
163
|
+
config,
|
|
164
|
+
__definition: fullDef
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
if (def.static) {
|
|
168
|
+
Object.assign(narrower, def.static);
|
|
169
|
+
}
|
|
170
|
+
return narrower;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
definePlatform
|
|
175
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import z__default from 'zod';
|
|
2
|
+
import { P as ProviderMessage, a as PlatformDef, b as Platform, c as PlatformProviderConfig, S as SpectrumLike, C as CustomEventStreams, d as Space, M as Message, e as ContentBuilder } from './types-eXHZpal1.js';
|
|
3
|
+
export { A as AnyPlatformDef, f as Content, E as EventProducer, g as PlatformInstance, h as PlatformMessage, i as PlatformSpace, j as PlatformUser, k as SchemaMessage, U as User, l as attachment, m as custom, t as text } from './types-eXHZpal1.js';
|
|
4
|
+
export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-DGy4geUK.js';
|
|
5
|
+
import 'hotscript';
|
|
6
|
+
import 'type-fest';
|
|
7
|
+
|
|
8
|
+
declare function definePlatform<_Name extends string, _ConfigSchema extends z__default.ZodType<object>, _UserSchema extends z__default.ZodType<object> | undefined, _SpaceSchema extends z__default.ZodType<object> | undefined, _SpaceParamsSchema extends z__default.ZodType<object> | undefined, _Client, _ResolvedUser extends {
|
|
9
|
+
id: string;
|
|
10
|
+
}, _ResolvedSpace extends {
|
|
11
|
+
id: string;
|
|
12
|
+
}, _MessageSchema extends z__default.ZodType<object> | undefined = undefined, _MessageType extends ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>> = ProviderMessage<_ResolvedUser, _ResolvedSpace, _MessageSchema extends z__default.ZodType<object> ? z__default.infer<_MessageSchema> : Record<never, never>>, _Events extends {
|
|
13
|
+
messages: (ctx: {
|
|
14
|
+
client: _Client;
|
|
15
|
+
config: z__default.infer<_ConfigSchema>;
|
|
16
|
+
}) => AsyncIterable<_MessageType>;
|
|
17
|
+
} = {
|
|
18
|
+
messages: (ctx: {
|
|
19
|
+
client: _Client;
|
|
20
|
+
config: z__default.infer<_ConfigSchema>;
|
|
21
|
+
}) => AsyncIterable<_MessageType>;
|
|
22
|
+
}, _Static extends Record<string, unknown> = Record<never, never>>(name: _Name, def: Omit<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events>, "name"> & {
|
|
23
|
+
static?: _Static;
|
|
24
|
+
}): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events>> & Readonly<_Static>;
|
|
25
|
+
|
|
26
|
+
type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> = SpectrumLike<Providers> & CustomEventStreams<Providers> & {
|
|
27
|
+
readonly messages: AsyncIterable<[Space, Message]>;
|
|
28
|
+
stop(): Promise<void>;
|
|
29
|
+
send(space: Space, ...content: [ContentBuilder, ...ContentBuilder[]]): Promise<void>;
|
|
30
|
+
responding<T>(space: Space, fn: () => T | Promise<T>): Promise<T>;
|
|
31
|
+
};
|
|
32
|
+
declare function Spectrum<const Providers extends PlatformProviderConfig[]>(options: {
|
|
33
|
+
projectId: string;
|
|
34
|
+
projectSecret: string;
|
|
35
|
+
providers: [...Providers];
|
|
36
|
+
} | {
|
|
37
|
+
projectId?: never;
|
|
38
|
+
projectSecret?: never;
|
|
39
|
+
providers: [...Providers];
|
|
40
|
+
}): Promise<SpectrumInstance<Providers>>;
|
|
41
|
+
|
|
42
|
+
export { ContentBuilder, Message, Platform, PlatformDef, PlatformProviderConfig, Space, Spectrum, type SpectrumInstance, definePlatform };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergeStreams,
|
|
3
|
+
stream
|
|
4
|
+
} from "./chunk-3TBRO2J7.js";
|
|
5
|
+
import {
|
|
6
|
+
definePlatform
|
|
7
|
+
} from "./chunk-UZ2CXPOD.js";
|
|
8
|
+
|
|
9
|
+
// src/spectrum.ts
|
|
10
|
+
import z from "zod";
|
|
11
|
+
var providerMessageCoreKeys = /* @__PURE__ */ new Set([
|
|
12
|
+
"content",
|
|
13
|
+
"id",
|
|
14
|
+
"sender",
|
|
15
|
+
"space",
|
|
16
|
+
"timestamp"
|
|
17
|
+
]);
|
|
18
|
+
var spectrumConfigSchema = z.union([
|
|
19
|
+
z.object({
|
|
20
|
+
projectId: z.string().min(1),
|
|
21
|
+
projectSecret: z.string().min(1),
|
|
22
|
+
providers: z.array(z.custom())
|
|
23
|
+
}),
|
|
24
|
+
z.object({
|
|
25
|
+
projectId: z.undefined().optional(),
|
|
26
|
+
projectSecret: z.undefined().optional(),
|
|
27
|
+
providers: z.array(z.custom())
|
|
28
|
+
})
|
|
29
|
+
]);
|
|
30
|
+
async function Spectrum(options) {
|
|
31
|
+
spectrumConfigSchema.parse(options);
|
|
32
|
+
const { projectId, projectSecret, providers } = options;
|
|
33
|
+
const platformStates = /* @__PURE__ */ new Map();
|
|
34
|
+
const customEventStreams = /* @__PURE__ */ new Map();
|
|
35
|
+
let stopped = false;
|
|
36
|
+
for (const provider of providers) {
|
|
37
|
+
const providerConfig = provider;
|
|
38
|
+
const def = providerConfig.__definition;
|
|
39
|
+
const userConfig = def.config.parse(providerConfig.config);
|
|
40
|
+
const client = await def.lifecycle.createClient({
|
|
41
|
+
config: userConfig,
|
|
42
|
+
projectId,
|
|
43
|
+
projectSecret
|
|
44
|
+
});
|
|
45
|
+
platformStates.set(def.name, {
|
|
46
|
+
client,
|
|
47
|
+
config: userConfig,
|
|
48
|
+
definition: def
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const adaptIterable = (iterable) => {
|
|
52
|
+
return stream((emit, end) => {
|
|
53
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
54
|
+
(async () => {
|
|
55
|
+
try {
|
|
56
|
+
let result = await iterator.next();
|
|
57
|
+
while (!result.done) {
|
|
58
|
+
emit(result.value);
|
|
59
|
+
result = await iterator.next();
|
|
60
|
+
}
|
|
61
|
+
end();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
end(error);
|
|
64
|
+
}
|
|
65
|
+
})();
|
|
66
|
+
return async () => {
|
|
67
|
+
await iterator.return?.();
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
const createProviderMessagesStream = (state) => {
|
|
72
|
+
const { client, config, definition } = state;
|
|
73
|
+
const raw = definition.events.messages({
|
|
74
|
+
client,
|
|
75
|
+
config
|
|
76
|
+
});
|
|
77
|
+
const bindSend = async function* () {
|
|
78
|
+
for await (const msg of raw) {
|
|
79
|
+
const extraEntries = Object.entries(msg).filter(
|
|
80
|
+
([key]) => !providerMessageCoreKeys.has(key)
|
|
81
|
+
);
|
|
82
|
+
const extra = Object.fromEntries(extraEntries);
|
|
83
|
+
const parsedExtra = definition.message?.schema ? definition.message.schema.parse(extra) : {};
|
|
84
|
+
const spaceRef = {
|
|
85
|
+
...msg.space,
|
|
86
|
+
__platform: definition.name
|
|
87
|
+
};
|
|
88
|
+
const typingCtx = { space: spaceRef, client, config };
|
|
89
|
+
const space = {
|
|
90
|
+
...spaceRef,
|
|
91
|
+
send: async (...content) => {
|
|
92
|
+
const resolved = await Promise.all(content.map((c) => c.build()));
|
|
93
|
+
await definition.actions.send({
|
|
94
|
+
...typingCtx,
|
|
95
|
+
content: resolved
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
startTyping: async () => {
|
|
99
|
+
await definition.actions.startTyping?.(typingCtx);
|
|
100
|
+
},
|
|
101
|
+
stopTyping: async () => {
|
|
102
|
+
await definition.actions.stopTyping?.(typingCtx);
|
|
103
|
+
},
|
|
104
|
+
responding: async (fn) => {
|
|
105
|
+
await definition.actions.startTyping?.(typingCtx);
|
|
106
|
+
try {
|
|
107
|
+
return await fn();
|
|
108
|
+
} finally {
|
|
109
|
+
await definition.actions.stopTyping?.(typingCtx).catch(() => {
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const normalizedMessage = {
|
|
115
|
+
...parsedExtra,
|
|
116
|
+
id: msg.id,
|
|
117
|
+
content: msg.content,
|
|
118
|
+
platform: definition.name,
|
|
119
|
+
react: async (reaction) => {
|
|
120
|
+
if (!definition.actions.reactToMessage) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
await definition.actions.reactToMessage({
|
|
124
|
+
space: spaceRef,
|
|
125
|
+
messageId: msg.id,
|
|
126
|
+
reaction,
|
|
127
|
+
client,
|
|
128
|
+
config
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
reply: async (...content) => {
|
|
132
|
+
if (!definition.actions.replyToMessage) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const resolved = await Promise.all(content.map((c) => c.build()));
|
|
136
|
+
await definition.actions.replyToMessage({
|
|
137
|
+
space: spaceRef,
|
|
138
|
+
messageId: msg.id,
|
|
139
|
+
content: resolved,
|
|
140
|
+
client,
|
|
141
|
+
config
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
sender: {
|
|
145
|
+
...msg.sender,
|
|
146
|
+
__platform: definition.name
|
|
147
|
+
},
|
|
148
|
+
space,
|
|
149
|
+
timestamp: msg.timestamp ?? /* @__PURE__ */ new Date()
|
|
150
|
+
};
|
|
151
|
+
yield [space, normalizedMessage];
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
return adaptIterable(bindSend());
|
|
155
|
+
};
|
|
156
|
+
const createMessagesStream = () => {
|
|
157
|
+
return stream(async (emit, end) => {
|
|
158
|
+
const merged = mergeStreams(
|
|
159
|
+
Array.from(platformStates.values(), createProviderMessagesStream)
|
|
160
|
+
);
|
|
161
|
+
(async () => {
|
|
162
|
+
try {
|
|
163
|
+
for await (const value of merged) {
|
|
164
|
+
emit(value);
|
|
165
|
+
}
|
|
166
|
+
end();
|
|
167
|
+
} catch (error) {
|
|
168
|
+
end(error);
|
|
169
|
+
}
|
|
170
|
+
})();
|
|
171
|
+
return async () => {
|
|
172
|
+
await merged.close();
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
const createCustomEventStream = (eventName) => {
|
|
177
|
+
return stream(async (emit, end) => {
|
|
178
|
+
const providerStreams = Array.from(platformStates.values(), (state) => {
|
|
179
|
+
const { client, config, definition } = state;
|
|
180
|
+
const producer = definition.events[eventName];
|
|
181
|
+
if (!producer) {
|
|
182
|
+
return void 0;
|
|
183
|
+
}
|
|
184
|
+
const providerEvents = producer({ client, config });
|
|
185
|
+
const annotatePlatform = async function* () {
|
|
186
|
+
for await (const value of providerEvents) {
|
|
187
|
+
yield { ...value, platform: definition.name };
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
return adaptIterable(annotatePlatform());
|
|
191
|
+
}).filter(
|
|
192
|
+
(value) => value !== void 0
|
|
193
|
+
);
|
|
194
|
+
const merged = mergeStreams(providerStreams);
|
|
195
|
+
(async () => {
|
|
196
|
+
try {
|
|
197
|
+
for await (const value of merged) {
|
|
198
|
+
emit(value);
|
|
199
|
+
}
|
|
200
|
+
end();
|
|
201
|
+
} catch (error) {
|
|
202
|
+
end(error);
|
|
203
|
+
}
|
|
204
|
+
})();
|
|
205
|
+
return async () => {
|
|
206
|
+
await merged.close();
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
const messagesStream = createMessagesStream();
|
|
211
|
+
const stopOnce = async () => {
|
|
212
|
+
if (stopped) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
stopped = true;
|
|
216
|
+
const streamShutdowns = [
|
|
217
|
+
messagesStream.close(),
|
|
218
|
+
...Array.from(
|
|
219
|
+
customEventStreams.values(),
|
|
220
|
+
(eventStream) => eventStream.close()
|
|
221
|
+
)
|
|
222
|
+
];
|
|
223
|
+
process.off("SIGINT", handleSignal);
|
|
224
|
+
process.off("SIGTERM", handleSignal);
|
|
225
|
+
await Promise.allSettled(streamShutdowns);
|
|
226
|
+
const clientShutdowns = Array.from(
|
|
227
|
+
platformStates.values(),
|
|
228
|
+
(state) => state.definition.lifecycle.destroyClient({
|
|
229
|
+
client: state.client
|
|
230
|
+
})
|
|
231
|
+
);
|
|
232
|
+
await Promise.allSettled(clientShutdowns);
|
|
233
|
+
customEventStreams.clear();
|
|
234
|
+
platformStates.clear();
|
|
235
|
+
};
|
|
236
|
+
const handleSignal = () => {
|
|
237
|
+
setTimeout(() => process.exit(1), 3e3).unref();
|
|
238
|
+
stopOnce().then(() => process.exit(0)).catch(() => process.exit(1));
|
|
239
|
+
};
|
|
240
|
+
process.on("SIGINT", handleSignal);
|
|
241
|
+
process.on("SIGTERM", handleSignal);
|
|
242
|
+
const messages = messagesStream;
|
|
243
|
+
const customEventProxy = new Proxy(
|
|
244
|
+
{},
|
|
245
|
+
{
|
|
246
|
+
get(_target, prop) {
|
|
247
|
+
let eventStream = customEventStreams.get(prop);
|
|
248
|
+
if (!eventStream) {
|
|
249
|
+
eventStream = createCustomEventStream(prop);
|
|
250
|
+
customEventStreams.set(prop, eventStream);
|
|
251
|
+
}
|
|
252
|
+
return eventStream;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
const base = {
|
|
257
|
+
__providers: providers,
|
|
258
|
+
__internal: { platforms: platformStates },
|
|
259
|
+
messages,
|
|
260
|
+
stop: stopOnce,
|
|
261
|
+
send: async (space, ...content) => {
|
|
262
|
+
await space.send(...content);
|
|
263
|
+
},
|
|
264
|
+
responding: async (space, fn) => {
|
|
265
|
+
return space.responding(fn);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
return new Proxy(base, {
|
|
269
|
+
get(target, prop, receiver) {
|
|
270
|
+
if (prop in target) {
|
|
271
|
+
return Reflect.get(target, prop, receiver);
|
|
272
|
+
}
|
|
273
|
+
if (typeof prop === "string") {
|
|
274
|
+
return customEventProxy[prop];
|
|
275
|
+
}
|
|
276
|
+
return void 0;
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/types/content.ts
|
|
282
|
+
import { readFile } from "fs/promises";
|
|
283
|
+
import { basename } from "path";
|
|
284
|
+
import { lookup as lookupMimeType } from "mime-types";
|
|
285
|
+
import z2 from "zod";
|
|
286
|
+
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
287
|
+
var contentSchema = z2.discriminatedUnion("type", [
|
|
288
|
+
z2.object({
|
|
289
|
+
type: z2.literal("plain_text"),
|
|
290
|
+
text: z2.string().nonempty()
|
|
291
|
+
}),
|
|
292
|
+
z2.object({
|
|
293
|
+
type: z2.literal("custom"),
|
|
294
|
+
raw: z2.json()
|
|
295
|
+
}),
|
|
296
|
+
z2.object({
|
|
297
|
+
type: z2.literal("attachment"),
|
|
298
|
+
data: z2.instanceof(Buffer),
|
|
299
|
+
mimeType: z2.string().nonempty(),
|
|
300
|
+
name: z2.string().nonempty()
|
|
301
|
+
})
|
|
302
|
+
]);
|
|
303
|
+
function text(text2) {
|
|
304
|
+
return {
|
|
305
|
+
build: () => Promise.resolve({ type: "plain_text", text: text2 })
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function custom(raw) {
|
|
309
|
+
return {
|
|
310
|
+
build: () => Promise.resolve({ type: "custom", raw })
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
|
|
314
|
+
var resolveAttachmentMimeType = (name, mimeType) => {
|
|
315
|
+
if (mimeType) {
|
|
316
|
+
return mimeType;
|
|
317
|
+
}
|
|
318
|
+
const resolvedMimeType = lookupMimeType(name);
|
|
319
|
+
if (!resolvedMimeType) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
return resolvedMimeType;
|
|
325
|
+
};
|
|
326
|
+
function attachment(input, options) {
|
|
327
|
+
return {
|
|
328
|
+
build: async () => {
|
|
329
|
+
const data = typeof input === "string" ? await readFile(input) : input;
|
|
330
|
+
const name = resolveAttachmentName(input, options?.name);
|
|
331
|
+
return {
|
|
332
|
+
data,
|
|
333
|
+
mimeType: resolveAttachmentMimeType(name, options?.mimeType),
|
|
334
|
+
name,
|
|
335
|
+
type: "attachment"
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
export {
|
|
341
|
+
Spectrum,
|
|
342
|
+
attachment,
|
|
343
|
+
custom,
|
|
344
|
+
definePlatform,
|
|
345
|
+
mergeStreams,
|
|
346
|
+
stream,
|
|
347
|
+
text
|
|
348
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { M as ManagedStream } from '../../stream-DGy4geUK.js';
|
|
2
|
+
import { AdvancedIMessage } from '@photon-ai/advanced-imessage';
|
|
3
|
+
import { IMessageSDK } from '@photon-ai/imessage-kit';
|
|
4
|
+
import * as z from 'zod';
|
|
5
|
+
import z__default from 'zod';
|
|
6
|
+
import { k as SchemaMessage, b as Platform, a as PlatformDef, P as ProviderMessage } from '../../types-eXHZpal1.js';
|
|
7
|
+
import * as zod_v4_core from 'zod/v4/core';
|
|
8
|
+
import 'hotscript';
|
|
9
|
+
import 'type-fest';
|
|
10
|
+
|
|
11
|
+
type IMessageClient = IMessageSDK | AdvancedIMessage[];
|
|
12
|
+
declare const userSchema: z__default.ZodObject<{}, z__default.core.$strip>;
|
|
13
|
+
declare const spaceSchema: z__default.ZodObject<{
|
|
14
|
+
id: z__default.ZodString;
|
|
15
|
+
type: z__default.ZodEnum<{
|
|
16
|
+
dm: "dm";
|
|
17
|
+
group: "group";
|
|
18
|
+
}>;
|
|
19
|
+
}, z__default.core.$strip>;
|
|
20
|
+
type IMessageMessage = SchemaMessage<typeof userSchema, typeof spaceSchema>;
|
|
21
|
+
|
|
22
|
+
declare const imessage: Platform<PlatformDef<"iMessage", z.ZodUnion<readonly [z.ZodObject<{
|
|
23
|
+
local: z.ZodLiteral<true>;
|
|
24
|
+
}, zod_v4_core.$strip>, z.ZodObject<{
|
|
25
|
+
local: z.ZodDefault<z.ZodOptional<z.ZodLiteral<false>>>;
|
|
26
|
+
clients: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
27
|
+
address: z.ZodString;
|
|
28
|
+
token: z.ZodString;
|
|
29
|
+
}, zod_v4_core.$strip>, z.ZodArray<z.ZodObject<{
|
|
30
|
+
address: z.ZodString;
|
|
31
|
+
token: z.ZodString;
|
|
32
|
+
}, zod_v4_core.$strip>>]>>;
|
|
33
|
+
}, zod_v4_core.$strip>]>, z.ZodType<object, unknown, zod_v4_core.$ZodTypeInternals<object, unknown>> | undefined, z.ZodObject<{
|
|
34
|
+
id: z.ZodString;
|
|
35
|
+
type: z.ZodEnum<{
|
|
36
|
+
dm: "dm";
|
|
37
|
+
group: "group";
|
|
38
|
+
}>;
|
|
39
|
+
}, zod_v4_core.$strip>, z.ZodType<object, unknown, zod_v4_core.$ZodTypeInternals<object, unknown>> | undefined, IMessageClient, {
|
|
40
|
+
id: string;
|
|
41
|
+
}, {
|
|
42
|
+
id: string;
|
|
43
|
+
type: "dm";
|
|
44
|
+
} | {
|
|
45
|
+
id: string;
|
|
46
|
+
type: "group";
|
|
47
|
+
}, undefined, ProviderMessage<{
|
|
48
|
+
id: string;
|
|
49
|
+
}, {
|
|
50
|
+
id: string;
|
|
51
|
+
type: "dm";
|
|
52
|
+
} | {
|
|
53
|
+
id: string;
|
|
54
|
+
type: "group";
|
|
55
|
+
}, Record<never, never>>, {
|
|
56
|
+
messages: ({ client }: {
|
|
57
|
+
client: IMessageClient;
|
|
58
|
+
config: {
|
|
59
|
+
local: true;
|
|
60
|
+
} | {
|
|
61
|
+
local: false;
|
|
62
|
+
clients?: {
|
|
63
|
+
address: string;
|
|
64
|
+
token: string;
|
|
65
|
+
} | {
|
|
66
|
+
address: string;
|
|
67
|
+
token: string;
|
|
68
|
+
}[] | undefined;
|
|
69
|
+
};
|
|
70
|
+
}) => ManagedStream<IMessageMessage>;
|
|
71
|
+
}>> & Readonly<{
|
|
72
|
+
tapbacks: {
|
|
73
|
+
readonly love: "love";
|
|
74
|
+
readonly like: "like";
|
|
75
|
+
readonly dislike: "dislike";
|
|
76
|
+
readonly laugh: "laugh";
|
|
77
|
+
readonly emphasize: "emphasize";
|
|
78
|
+
readonly question: "question";
|
|
79
|
+
};
|
|
80
|
+
}>;
|
|
81
|
+
|
|
82
|
+
export { imessage };
|