@yongdall/connection 0.4.0 → 0.5.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/index.d.mts CHANGED
@@ -1,37 +1,9 @@
1
- import { Hook } from "@yongdall/common";
2
1
  import { Connection, IConnection, MaybePromise } from "@yongdall/model";
3
2
  import { Readable } from "node:stream";
4
- import { Tenant } from "@yongdall/types";
5
3
  import * as imodel0 from "imodel";
4
+ import { Realm } from "@yongdall/types";
5
+ import "@yongdall/common";
6
6
 
7
- //#region packages/connection/main.d.mts
8
- /**
9
- *
10
- * @template {string} K
11
- * @param {K} type
12
- * @param {string} name
13
- * @param {Tenant?} [tenant]
14
- * @param {boolean} [isAlias]
15
- */
16
- declare function clear<K extends string>(type: K, name: string, tenant?: Tenant | null, isAlias?: boolean): Promise<void>;
17
- declare function stop(): Promise<void>;
18
- /**
19
- *
20
- * @template {string} K
21
- * @param {K} type
22
- * @param {string} [dbId]
23
- * @param {Tenant?} [tenant]
24
- * @returns {Connections[K]}
25
- */
26
- declare function connect<K extends string>(type: K, dbId?: string, tenant?: Tenant | null): Connections[K];
27
- /**
28
- * @template {string & keyof ProvidersConverted} T
29
- * @param {T} type
30
- * @param {string?} [dbId]
31
- * @returns {Connections[T]}
32
- */
33
- declare function useConnection<T extends string & keyof ProvidersConverted>(type: T, dbId?: string | null): Connections[T];
34
- //#endregion
35
7
  //#region packages/connection/rdb.d.mts
36
8
  /**
37
9
  * @param {string?} [dbId]
@@ -44,15 +16,15 @@ declare function useDatabase(dbId?: string | null): imodel0.Connection<any>;
44
16
  declare function transaction(...names: (string | null | (string | null)[])[]): (f: (this: T, ...p: P) => Promise<R>, ctx: ClassMethodDecoratorContext) => (this: T, ...p: P) => Promise<R>;
45
17
  //#endregion
46
18
  //#region packages/connection/mq.d.mts
47
- /** @import { Tenant } from '@yongdall/types' */
19
+ /** @import { Realm } from '@yongdall/types' */
48
20
  /**
49
21
  *
50
22
  * @param {string} channel
51
23
  * @param {any} message
52
24
  * @param {string} [service]
53
- * @param {Tenant?} [tenant]
25
+ * @param {Realm?} [realm]
54
26
  */
55
- declare function publishMessage(channel: string, message: any, service?: string, tenant?: Tenant | null): Promise<void>;
27
+ declare function publishMessage(channel: string, message: any, service?: string, realm?: Realm | null): Promise<void>;
56
28
  /**
57
29
  *
58
30
  * @param {string} channel
@@ -62,15 +34,15 @@ declare function publishMessage(channel: string, message: any, service?: string,
62
34
  declare function subscribeMessage(channel: string, listener: (val: any) => any, service?: string): () => void;
63
35
  //#endregion
64
36
  //#region packages/connection/tq.d.mts
65
- /** @import { Tenant } from '@yongdall/types' */
37
+ /** @import { Realm } from '@yongdall/types' */
66
38
  /**
67
39
  *
68
40
  * @param {string} queue
69
41
  * @param {any} message
70
42
  * @param {string} [service]
71
- * @param {Tenant?} [tenant]
43
+ * @param {Realm?} [realm]
72
44
  */
73
- declare function publishTask(queue: string, message: any, service?: string, tenant?: Tenant | null): Promise<void>;
45
+ declare function publishTask(queue: string, message: any, service?: string, realm?: Realm | null): Promise<void>;
74
46
  /**
75
47
  * @template T
76
48
  * @param {string} queue
@@ -79,6 +51,53 @@ declare function publishTask(queue: string, message: any, service?: string, tena
79
51
  */
80
52
  declare function waitTask<T>(queue: string, service?: string): Promise<T | void>;
81
53
  //#endregion
54
+ //#region packages/connection/cache.d.mts
55
+ /**
56
+ * @param {string?} [dbId]
57
+ */
58
+ declare function useCache(dbId?: string | null): {
59
+ set(key: string, field: string, value: any): PromiseLike<void>;
60
+ get<T>(key: string, field: string): PromiseLike<T | void>;
61
+ exists(key: string, field: string): PromiseLike<boolean>;
62
+ del(key: string, field: string): PromiseLike<void>;
63
+ clear(key: string): PromiseLike<void>;
64
+ setExpirable(key: string, field: string, value: any, ttl: number): PromiseLike<void>;
65
+ getExpirable<T>(key: string, field: string): PromiseLike<T | void>;
66
+ existsExpirable(key: string, field: string): PromiseLike<boolean>;
67
+ delExpirable(key: string, field: string): PromiseLike<void>;
68
+ memoize<T>(key: string, field: string, exec: () => PromiseLike<T> | T): PromiseLike<T>;
69
+ abort?(): void;
70
+ [Symbol.dispose](): void;
71
+ };
72
+ //#endregion
73
+ //#region packages/connection/main.d.mts
74
+ /**
75
+ *
76
+ * @template {string} K
77
+ * @param {K} type
78
+ * @param {string} name
79
+ * @param {Realm?} [realm]
80
+ * @param {boolean} [isAlias]
81
+ */
82
+ declare function clear<K extends string>(type: K, name: string, realm?: Realm | null, isAlias?: boolean): Promise<void>;
83
+ declare function stop(): Promise<void>;
84
+ /**
85
+ *
86
+ * @template {string} K
87
+ * @param {K} type
88
+ * @param {string} [dbId]
89
+ * @param {Realm?} [realm]
90
+ * @returns {Connections[K]}
91
+ */
92
+ declare function connect<K extends string>(type: K, dbId?: string, realm?: Realm | null): Connections[K];
93
+ /**
94
+ * @template {string & keyof ProvidersConverted} T
95
+ * @param {T} type
96
+ * @param {string?} [dbId]
97
+ * @returns {Connections[T]}
98
+ */
99
+ declare function useConnection<T extends string & keyof ProvidersConverted>(type: T, dbId?: string | null): Connections[T];
100
+ //#endregion
82
101
  //#region packages/connection/types.d.mts
83
102
  type Provider<T> = (uri: string) => T | PromiseLike<T>;
84
103
  interface MessageQueue {
@@ -96,6 +115,10 @@ interface Cache {
96
115
  exists(key: string, field: string): PromiseLike<boolean> | boolean;
97
116
  del(key: string, field: string): PromiseLike<void> | void;
98
117
  clear(key: string): PromiseLike<void> | void;
118
+ setExpirable(key: string, field: string, value: any, ttl: number): PromiseLike<void> | void;
119
+ getExpirable<T>(key: string, field: string): PromiseLike<T | void> | T | void;
120
+ existsExpirable(key: string, field: string): PromiseLike<boolean> | boolean;
121
+ delExpirable(key: string, field: string): PromiseLike<void> | void;
99
122
  disconnect(): void;
100
123
  }
101
124
  interface FileStore {
@@ -147,14 +170,17 @@ interface Connections {
147
170
  publish(queue: string, data: any): Promise<void>;
148
171
  get<T>(queue: string): Promise<T | void>;
149
172
  abort?(): void;
173
+ [Symbol.dispose](): void;
150
174
  };
151
175
  mq: {
152
176
  publish(channel: string, data: any): Promise<void>;
153
177
  subscribe(channel: string, subscriber: (data: any) => void): () => void;
154
178
  abort?(): void;
179
+ [Symbol.dispose](): void;
155
180
  };
156
181
  fs: FileStore & {
157
182
  abort?(): void;
183
+ [Symbol.dispose](): void;
158
184
  };
159
185
  cache: {
160
186
  set(key: string, field: string, value: any): PromiseLike<void>;
@@ -162,26 +188,25 @@ interface Connections {
162
188
  exists(key: string, field: string): PromiseLike<boolean>;
163
189
  del(key: string, field: string): PromiseLike<void>;
164
190
  clear(key: string): PromiseLike<void>;
191
+ setExpirable(key: string, field: string, value: any, ttl: number): PromiseLike<void>;
192
+ getExpirable<T>(key: string, field: string): PromiseLike<T | void>;
193
+ existsExpirable(key: string, field: string): PromiseLike<boolean>;
194
+ delExpirable(key: string, field: string): PromiseLike<void>;
165
195
  memoize<T>(key: string, field: string, exec: () => PromiseLike<T> | T): PromiseLike<T>;
166
196
  abort?(): void;
197
+ [Symbol.dispose](): void;
167
198
  };
168
199
  [k: string]: {
169
200
  abort?(): void;
201
+ [Symbol.dispose](): void;
170
202
  };
171
203
  }
172
- /** 应用配置 */
173
- interface Hooks {
174
- providers: { [K in keyof Providers]: Record<string, Provider<Providers[K]>> };
175
- providerDefines: { [K in keyof ProvidersConverted]: {
176
- label: string;
177
- convert: (vla: Providers[K]) => MaybePromise<ProvidersConverted[K]>;
178
- connect: (vla: Promise<ProvidersConverted[K]>) => Connections[K];
179
- default: ProvidersConverted[K];
180
- } };
181
- }
182
- declare namespace Hooks {
183
- type providers = Hook.Define<Hooks['providers']>;
184
- type providerDefines = Hook.Define<Hooks['providerDefines']>;
185
- }
204
+ type ProviderProfile = { [K in keyof Providers]: Record<string, Provider<Providers[K]>> };
205
+ type ProviderDefineProfile = { [K in keyof ProvidersConverted]: {
206
+ label: string;
207
+ convert: (vla: Providers[K]) => MaybePromise<ProvidersConverted[K]>;
208
+ connect: (vla: Promise<ProvidersConverted[K]>) => Connections[K];
209
+ default?: ProvidersConverted[K];
210
+ } };
186
211
  //#endregion
187
- export { Cache, Connections, FileStore, Hooks, MessageQueue, Provider, Providers, ProvidersConverted, TaskQueue, clear, connect, publishMessage, publishTask, stop, subscribeMessage, transaction, useConnection, useDatabase, waitTask };
212
+ export { Cache, Connections, FileStore, MessageQueue, Provider, ProviderDefineProfile, ProviderProfile, Providers, ProvidersConverted, TaskQueue, clear, connect, publishMessage, publishTask, stop, subscribeMessage, transaction, useCache, useConnection, useDatabase, waitTask };
package/index.mjs CHANGED
@@ -1,181 +1,5 @@
1
- import { Query } from "@yongdall/model";
2
- import { addFinally, createStore, has } from "@yongdall/context";
3
- import { getModel, hooks, useTenant } from "@yongdall/core";
1
+ import { a as useConnection, i as stop, n as connect, t as clear } from "./main-B_-mso2s.mjs";
4
2
 
5
- //#region packages/connection/main.mjs
6
- /** @import { Tenant } from '@yongdall/types' */
7
- /** @import {Connections, Hooks, Providers, ProvidersConverted} from './types.mjs' */
8
- /**
9
- * @returns {[
10
- * Hooks['providers'],
11
- * Hooks['providerDefines'],
12
- * ]}
13
- */
14
- function getProviders() {
15
- /** @type {[string, Hooks['providers'][keyof Hooks['providers']]][]} */
16
- const list = [...hooks.get("providers").values()].flatMap((v) => v ? Object.entries(v) : []);
17
- const allProviders = Object.assign(Object.create(null), Object.fromEntries(Object.entries(Object.groupBy(list, (v) => v[0])).map(([t, v]) => [t, v ? Object.assign(Object.create(null), ...v.map((v) => v[1])) : Object.create(null)])));
18
- /** @type {[string, Hooks['providerDefines'][keyof Hooks['providerDefines']]][]} */
19
- const list0 = [...hooks.get("providerDefines").values()].flatMap((v) => v ? Object.entries(v) : []);
20
- return [allProviders, Object.assign(Object.create(null), Object.fromEntries(list0))];
21
- }
22
- let [allProviders, allDefines] = getProviders();
23
- hooks.listen(() => {
24
- [allProviders, allDefines] = getProviders();
25
- }, -1e6);
26
- /**
27
- * @type {Record<string, { [K in keyof ProvidersConverted]: Record<string, Promise<ProvidersConverted[K]>>}>}
28
- */
29
- let allConnections = Object.create(null);
30
- /**
31
- *
32
- * @template {string} K
33
- * @param {K} type
34
- * @param {string} name
35
- * @param {Tenant?} [tenant]
36
- * @param {boolean} [isAlias]
37
- */
38
- async function clear(type, name, tenant, isAlias) {
39
- const tenantId = (tenant || await useTenant()).id;
40
- const tenantConnections = allConnections[tenantId];
41
- if (!tenantConnections) return;
42
- const connections = tenantConnections[type];
43
- if (!connections) return;
44
- const db = connections[name];
45
- delete connections[name];
46
- if (isAlias) return;
47
- return (await db)?.abort?.();
48
- }
49
- async function stop() {
50
- const oldConnections = allConnections;
51
- allConnections = Object.create(null);
52
- for (const tenantConnections of Object.values(oldConnections)) for (const connections of Object.values(tenantConnections)) for (const db of Object.values(connections)) (await db)?.abort?.();
53
- }
54
- /**
55
- *
56
- * @template {string} T
57
- * @param {T} type
58
- * @param {string} name
59
- * @param {Tenant} tenant
60
- * @returns {Promise<[uri: string, alias?: string]>}
61
- */
62
- async function getUri(type, name, tenant) {
63
- if (!name) {
64
- const provider = tenant.providers[type];
65
- return [typeof provider === "string" && provider || ""];
66
- }
67
- const model = await getModel("database");
68
- if (!model) return [""];
69
- let sql = new Query(model, true).where("type", type).where("name", name);
70
- sql = sql.select("uri");
71
- const aliasField = model.fields.alias;
72
- if (aliasField && aliasField.type === "string") sql = sql.select("alias");
73
- const a = await connect("rdb", "", tenant).first(sql);
74
- if (!a) return [""];
75
- const { uri, alias } = a;
76
- return [uri || "", alias];
77
- }
78
- /**
79
- *
80
- * @template {string & keyof Providers} K
81
- * @param {K} type
82
- * @param {string} [dbId]
83
- * @param {Tenant?} [tenant]
84
- */
85
- async function findConnection(type, dbId, tenant) {
86
- const currentTenant = tenant || await useTenant();
87
- const tenantId = currentTenant.id;
88
- let tenantConnections = allConnections[tenantId];
89
- if (!tenantConnections) {
90
- tenantConnections = Object.create(null);
91
- allConnections[tenantId] = tenantConnections;
92
- }
93
- /** @type {Record<string, Promise<ProvidersConverted[K]>>} */
94
- let connections = tenantConnections[type];
95
- if (!connections) {
96
- connections = Object.create(null);
97
- tenantConnections[type] = connections;
98
- }
99
- const dbName = String(dbId || "");
100
- const connection = connections[dbName];
101
- if (connection) return connection;
102
- const providers = allProviders[type];
103
- if (!providers) throw new Error(`不支持 ${type} 类型`);
104
- /**
105
- *
106
- * @param {string} uri
107
- * @returns
108
- */
109
- async function build(uri) {
110
- if (!uri) {
111
- /** @type {ProvidersConverted[K] | Providers[K]} */
112
- const conn = allDefines[type]?.default;
113
- if (conn) return conn;
114
- throw new Error(`找不到 URI (${type}, ${dbName})`);
115
- }
116
- const protocol = uri.split(":", 1)[0].split("+", 1)[0].toLowerCase();
117
- const provider = providers[protocol];
118
- if (typeof provider !== "function") throw new Error(`不支持 ${protocol} 协议`);
119
- const promise = await provider(uri);
120
- /** @type {ProvidersConverted[K] | Providers[K]} */
121
- const conn = allDefines[type]?.convert?.(promise) || promise;
122
- if (!conn) throw new Error();
123
- return conn;
124
- }
125
- const conn = getUri(type, dbName, currentTenant).then(([uri, alias]) => {
126
- if (!alias) return build(uri);
127
- const connection = connections[alias];
128
- if (connection) return connection;
129
- const conn = getUri(type, alias, currentTenant).then(([uri, alias]) => alias ? Promise.reject(/* @__PURE__ */ new Error()) : build(uri));
130
- connections[alias] = conn;
131
- return conn;
132
- });
133
- connections[dbName] = conn;
134
- return conn;
135
- }
136
- /**
137
- *
138
- * @template {string} K
139
- * @param {K} type
140
- * @param {string} [dbId]
141
- * @param {Tenant?} [tenant]
142
- * @returns {Connections[K]}
143
- */
144
- function connect(type, dbId, tenant) {
145
- const res = allDefines[type]?.connect?.(findConnection(type, dbId, tenant));
146
- if (!res) throw new Error();
147
- return res;
148
- }
149
- const [dbGetter, dbSetter] = createStore(null);
150
- /**
151
- * @template {string & keyof ProvidersConverted} T
152
- * @param {T} type
153
- * @param {string?} [dbId]
154
- * @returns {Connections[T]}
155
- */
156
- function useConnection(type, dbId) {
157
- has(true);
158
- let dbs = dbGetter();
159
- if (!dbs) {
160
- dbs = {};
161
- dbSetter(dbs);
162
- }
163
- let typed = dbs[type];
164
- if (!typed) {
165
- typed = {};
166
- dbs[type] = typed;
167
- }
168
- const dbName = String(dbId || "");
169
- if (Object.hasOwn(typed, dbName)) return typed[dbName];
170
- const db = connect(type, dbName);
171
- typed[dbName] = db;
172
- addFinally(() => {
173
- db.abort?.();
174
- });
175
- return db;
176
- }
177
-
178
- //#endregion
179
3
  //#region packages/connection/rdb.mjs
180
4
  /**
181
5
  * @param {string?} [dbId]
@@ -213,16 +37,16 @@ function transaction(...names) {
213
37
 
214
38
  //#endregion
215
39
  //#region packages/connection/mq.mjs
216
- /** @import { Tenant } from '@yongdall/types' */
40
+ /** @import { Realm } from '@yongdall/types' */
217
41
  /**
218
42
  *
219
43
  * @param {string} channel
220
44
  * @param {any} message
221
45
  * @param {string} [service]
222
- * @param {Tenant?} [tenant]
46
+ * @param {Realm?} [realm]
223
47
  */
224
- async function publishMessage(channel, message, service, tenant) {
225
- return connect("mq", service, tenant).publish(channel, message);
48
+ async function publishMessage(channel, message, service, realm) {
49
+ return connect("mq", service, realm).publish(channel, message);
226
50
  }
227
51
  /**
228
52
  *
@@ -236,16 +60,16 @@ function subscribeMessage(channel, listener, service) {
236
60
 
237
61
  //#endregion
238
62
  //#region packages/connection/tq.mjs
239
- /** @import { Tenant } from '@yongdall/types' */
63
+ /** @import { Realm } from '@yongdall/types' */
240
64
  /**
241
65
  *
242
66
  * @param {string} queue
243
67
  * @param {any} message
244
68
  * @param {string} [service]
245
- * @param {Tenant?} [tenant]
69
+ * @param {Realm?} [realm]
246
70
  */
247
- async function publishTask(queue, message, service, tenant) {
248
- return connect("tq", service, tenant).publish(queue, message);
71
+ async function publishTask(queue, message, service, realm) {
72
+ return connect("tq", service, realm).publish(queue, message);
249
73
  }
250
74
  /**
251
75
  * @template T
@@ -258,5 +82,14 @@ function waitTask(queue, service) {
258
82
  }
259
83
 
260
84
  //#endregion
261
- export { clear, connect, publishMessage, publishTask, stop, subscribeMessage, transaction, useConnection, useDatabase, waitTask };
85
+ //#region packages/connection/cache.mjs
86
+ /**
87
+ * @param {string?} [dbId]
88
+ */
89
+ function useCache(dbId) {
90
+ return useConnection("cache", dbId);
91
+ }
92
+
93
+ //#endregion
94
+ export { clear, connect, publishMessage, publishTask, stop, subscribeMessage, transaction, useCache, useConnection, useDatabase, waitTask };
262
95
  //# sourceMappingURL=index.mjs.map
package/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../packages/connection/main.mjs","../../packages/connection/rdb.mjs","../../packages/connection/mq.mjs","../../packages/connection/tq.mjs"],"sourcesContent":["import { addFinally, createStore, has } from '@yongdall/context';\nimport { getModel, useTenant, hooks } from '@yongdall/core';\nimport { Query } from '@yongdall/model';\n/** @import { Tenant } from '@yongdall/types' */\n\n/** @import {Connections, Hooks, Providers, ProvidersConverted} from './types.mjs' */\n\n\n\n\n/**\n * @returns {[\n * Hooks['providers'],\n * Hooks['providerDefines'],\n * ]}\n */\nfunction getProviders() {\n\n\t/** @type {[string, Hooks['providers'][keyof Hooks['providers']]][]} */\n\tconst list = [...hooks.get('providers').values()].flatMap(v => v ? Object.entries(v) : []);\n\tconst allProviders = Object.assign(Object.create(null), Object.fromEntries(\n\t\tObject.entries(Object.groupBy(list, v => v[0])).map(([t, v]) => [\n\t\t\tt, v ? Object.assign(Object.create(null), ...v.map(v => v[1])) : Object.create(null)\n\t\t]),\n\t));\n\t/** @type {[string, Hooks['providerDefines'][keyof Hooks['providerDefines']]][]} */\n\tconst list0 = [...hooks.get('providerDefines').values()].flatMap(v => v ? Object.entries(v) : []);\n\tconst allDefines = Object.assign(Object.create(null), Object.fromEntries(list0));\n\n\n\treturn [allProviders, allDefines];\n}\nlet [allProviders, allDefines] = getProviders();\nhooks.listen(() => {\n\t[allProviders, allDefines] = getProviders();\n}, -1000000);\n\n\n/**\n * @type {Record<string, { [K in keyof ProvidersConverted]: Record<string, Promise<ProvidersConverted[K]>>}>}\n */\nlet allConnections = Object.create(null);\n/**\n * \n * @template {string} K\n * @param {K} type\n * @param {string} name \n * @param {Tenant?} [tenant] \n * @param {boolean} [isAlias] \n */\nexport async function clear(type, name, tenant, isAlias) {\n\tconst tenantId = (tenant || await useTenant()).id;\n\tconst tenantConnections = allConnections[tenantId];\n\tif (!tenantConnections) { return; }\n\tconst connections = tenantConnections[type];\n\tif (!connections) { return; }\n\tconst db = connections[name];\n\tdelete connections[name];\n\tif (isAlias) { return }\n\tconst k = await db;\n\treturn k?.abort?.();\n}\nexport async function stop() {\n\tconst oldConnections = allConnections;\n\tallConnections = Object.create(null);\n\tfor (const tenantConnections of Object.values(oldConnections)) {\n\t\tfor (const connections of Object.values(tenantConnections)) {\n\t\t\tfor (const db of Object.values(connections)) {\n\t\t\t\tconst k = await db;\n\t\t\t\tk?.abort?.();\n\t\t\t}\n\t\t}\n\t}\n\n}\n/**\n * \n * @template {string} T\n * @param {T} type\n * @param {string} name \n * @param {Tenant} tenant \n * @returns {Promise<[uri: string, alias?: string]>}\n */\nasync function getUri(type, name, tenant) {\n\tif (!name) {\n\t\tconst provider = tenant.providers[type];\n\t\treturn [typeof provider === 'string' && provider || ''];\n\t}\n\tconst model = await getModel('database');\n\tif (!model) { return ['']; }\n\tconst modelQuery = new Query(model, true);\n\tlet sql = modelQuery.where('type', type).where('name', name);\n\tsql = sql.select('uri');\n\tconst aliasField = model.fields.alias;\n\tif (aliasField && aliasField.type === 'string') { sql = sql.select('alias'); }\n\tconst a = await connect('rdb', '', tenant).first(sql);\n\tif (!a) { return ['']; }\n\tconst { uri, alias } = a;\n\treturn [uri || '', alias];\n}\n\n\n/**\n * \n * @template {string & keyof Providers} K\n * @param {K} type\n * @param {string} [dbId] \n * @param {Tenant?} [tenant] \n */\nasync function findConnection(type, dbId, tenant) {\n\tconst currentTenant = tenant || await useTenant();\n\tconst tenantId = currentTenant.id;\n\tlet tenantConnections = allConnections[tenantId];\n\tif (!tenantConnections) {\n\t\ttenantConnections = Object.create(null);\n\t\tallConnections[tenantId] = tenantConnections;\n\t}\n\t/** @type {Record<string, Promise<ProvidersConverted[K]>>} */\n\tlet connections = tenantConnections[type];\n\tif (!connections) {\n\t\tconnections = Object.create(null);\n\t\ttenantConnections[type] = connections;\n\t}\n\tconst dbName = String(dbId || '');\n\tconst connection = connections[dbName];\n\tif (connection) { return connection; }\n\tconst providers = allProviders[type];\n\tif (!providers) { throw new Error(`不支持 ${type} 类型`); }\n\t/**\n\t * \n\t * @param {string} uri \n\t * @returns \n\t */\n\tasync function build(uri) {\n\t\tif (!uri) {\n\t\t\t/** @type {ProvidersConverted[K] | Providers[K]} */\n\t\t\tconst conn = allDefines[type]?.default;\n\t\t\tif (conn) { return conn; }\n\t\t\tthrow new Error(`找不到 URI (${type}, ${dbName})`);\n\t\t}\n\t\tconst protocol = uri.split(':', 1)[0].split('+', 1)[0].toLowerCase();\n\t\tconst provider = providers[protocol];\n\t\tif (typeof provider !== 'function') {\n\t\t\tthrow new Error(`不支持 ${protocol} 协议`);\n\t\t}\n\t\tconst promise = await provider(uri);\n\t\t/** @type {ProvidersConverted[K] | Providers[K]} */\n\t\tconst conn = allDefines[type]?.convert?.(promise) || promise;\n\t\tif (!conn) { throw new Error(); }\n\t\treturn conn;\n\t}\n\tconst conn = getUri(type, dbName, currentTenant).then(([uri, alias]) => {\n\t\tif (!alias) { return build(uri); }\n\t\tconst connection = connections[alias];\n\t\tif (connection) { return connection; }\n\t\tconst conn = getUri(type, alias, currentTenant).then(([uri, alias]) => alias ? Promise.reject(new Error) : build(uri));\n\t\tconnections[alias] = conn;\n\t\treturn conn;\n\t});\n\tconnections[dbName] = conn;\n\treturn conn;\n}\n\n/**\n * \n * @template {string} K\n * @param {K} type\n * @param {string} [dbId] \n * @param {Tenant?} [tenant] \n * @returns {Connections[K]}\n */\nexport function connect(type, dbId, tenant) {\n\tconst res = allDefines[type]?.connect?.(findConnection(type, dbId, tenant));\n\tif (!res) {\n\t\tthrow new Error();\n\t}\n\treturn res;\n}\n\n\n\nconst [dbGetter, dbSetter] = createStore(/** @type {{ [K in keyof Connections]?: Record<String, Connections[K]>}?} */(null));\n\n/**\n * @template {string & keyof ProvidersConverted} T\n * @param {T} type\n * @param {string?} [dbId]\n * @returns {Connections[T]}\n */\nexport function useConnection(type, dbId) {\n\thas(true);\n\tlet dbs = dbGetter();\n\tif (!dbs) {\n\t\tdbs = {};\n\t\tdbSetter(dbs);\n\t}\n\tlet typed = dbs[type];\n\tif (!typed) {\n\t\ttyped = {};\n\t\tdbs[type] = typed;\n\t}\n\tconst dbName = String(dbId || '');\n\tif (Object.hasOwn(typed, dbName)) {\n\t\treturn typed[dbName];\n\t}\n\tconst db = connect(type, dbName);\n\ttyped[dbName] = db;\n\taddFinally(() => { db.abort?.(); });\n\treturn db;\n}\n","import { useConnection } from './main.mjs';\n\n\n\n/**\n * @param {string?} [dbId]\n */\nexport function useDatabase(dbId) {\n\treturn useConnection('rdb', dbId);\n}\n\n/**\n * \n * @param {...string | null | (string | null)[]} names \n */\nexport function transaction(...names) {\n\tconst allNames = new Set(names.flat().filter(v => v && typeof v === 'string' || v === null));\n\tif (!allNames.size) {\n\t\tallNames.add(null);\n\t}\n\t/**\n\t * @template {any[]} P\n\t * @template {any} R\n\t * @template {any} T\n\t * @param {(this:T, ...p: P) => Promise<R>} f\n\t * @param {ClassMethodDecoratorContext} ctx\n\t * @returns {(this:T, ...p: P) => Promise<R>}\n\t */\n\treturn function decorator(f, ctx) {\n\t\t// TODO: 修饰器\n\t\tif (typeof f !== 'function') {\n\t\t\tthrow new Error('事务修饰器只能加在方法上');\n\t\t}\n\t\tif (ctx.kind !== 'method') {\n\t\t\tthrow new Error('事务修饰器只能加在方法上');\n\t\t}\n\t\tlet fn = f;\n\t\tfor (const name of allNames) {\n\t\t\tfn = async function(...p) {\n\t\t\t\treturn useDatabase(name).transaction(signal => {\n\t\t\t\t\treturn f.apply(this, p);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn fn;\n\t}\n}\n","import { connect } from './main.mjs';\n/** @import { Tenant } from '@yongdall/types' */\n\n/**\n * \n * @param {string} channel \n * @param {any} message \n * @param {string} [service] \n * @param {Tenant?} [tenant]\n */\nexport async function publishMessage(channel, message, service, tenant) {\n\treturn connect('mq', service, tenant).publish(channel, message);\n}\n\n\n\n/**\n * \n * @param {string} channel \n * @param {(val: any) => any} listener\n * @param {string} [service] \n */\nexport function subscribeMessage(channel, listener, service) {\n\treturn connect('mq', service).subscribe(channel, listener);\n}\n","import { connect } from './main.mjs';\n/** @import { Tenant } from '@yongdall/types' */\n\n/**\n * \n * @param {string} queue \n * @param {any} message \n * @param {string} [service] \n * @param {Tenant?} [tenant]\n */\nexport async function publishTask(queue, message, service, tenant) {\n\treturn connect('tq', service, tenant).publish(queue, message);\n}\n\n/**\n * @template T\n * @param {string} queue \n * @param {string} [service] \n * @returns {Promise<T | void>}\n */\nexport function waitTask(queue, service) {\n\treturn connect('tq', service).get(queue);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../packages/connection/rdb.mjs","../../packages/connection/mq.mjs","../../packages/connection/tq.mjs","../../packages/connection/cache.mjs"],"sourcesContent":["import { useConnection } from './main.mjs';\n\n\n\n/**\n * @param {string?} [dbId]\n */\nexport function useDatabase(dbId) {\n\treturn useConnection('rdb', dbId);\n}\n\n/**\n * \n * @param {...string | null | (string | null)[]} names \n */\nexport function transaction(...names) {\n\tconst allNames = new Set(names.flat().filter(v => v && typeof v === 'string' || v === null));\n\tif (!allNames.size) {\n\t\tallNames.add(null);\n\t}\n\t/**\n\t * @template {any[]} P\n\t * @template {any} R\n\t * @template {any} T\n\t * @param {(this:T, ...p: P) => Promise<R>} f\n\t * @param {ClassMethodDecoratorContext} ctx\n\t * @returns {(this:T, ...p: P) => Promise<R>}\n\t */\n\treturn function decorator(f, ctx) {\n\t\t// TODO: 修饰器\n\t\tif (typeof f !== 'function') {\n\t\t\tthrow new Error('事务修饰器只能加在方法上');\n\t\t}\n\t\tif (ctx.kind !== 'method') {\n\t\t\tthrow new Error('事务修饰器只能加在方法上');\n\t\t}\n\t\tlet fn = f;\n\t\tfor (const name of allNames) {\n\t\t\tfn = async function(...p) {\n\t\t\t\treturn useDatabase(name).transaction(signal => {\n\t\t\t\t\treturn f.apply(this, p);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn fn;\n\t}\n}\n","import { connect } from './main.mjs';\n/** @import { Realm } from '@yongdall/types' */\n\n/**\n * \n * @param {string} channel \n * @param {any} message \n * @param {string} [service] \n * @param {Realm?} [realm]\n */\nexport async function publishMessage(channel, message, service, realm) {\n\treturn connect('mq', service, realm).publish(channel, message);\n}\n\n\n\n/**\n * \n * @param {string} channel \n * @param {(val: any) => any} listener\n * @param {string} [service] \n */\nexport function subscribeMessage(channel, listener, service) {\n\treturn connect('mq', service).subscribe(channel, listener);\n}\n","import { connect } from './main.mjs';\n/** @import { Realm } from '@yongdall/types' */\n\n/**\n * \n * @param {string} queue \n * @param {any} message \n * @param {string} [service] \n * @param {Realm?} [realm]\n */\nexport async function publishTask(queue, message, service, realm) {\n\treturn connect('tq', service, realm).publish(queue, message);\n}\n\n/**\n * @template T\n * @param {string} queue \n * @param {string} [service] \n * @returns {Promise<T | void>}\n */\nexport function waitTask(queue, service) {\n\treturn connect('tq', service).get(queue);\n}\n","import { useConnection } from './main.mjs';\n\n\n\n/**\n * @param {string?} [dbId]\n */\nexport function useCache(dbId) {\n\treturn useConnection('cache', dbId);\n}\n"],"mappings":";;;;;;AAOA,SAAgB,YAAY,MAAM;AACjC,QAAO,cAAc,OAAO,KAAK;;;;;;AAOlC,SAAgB,YAAY,GAAG,OAAO;CACrC,MAAM,WAAW,IAAI,IAAI,MAAM,MAAM,CAAC,QAAO,MAAK,KAAK,OAAO,MAAM,YAAY,MAAM,KAAK,CAAC;AAC5F,KAAI,CAAC,SAAS,KACb,UAAS,IAAI,KAAK;;;;;;;;;AAUnB,QAAO,SAAS,UAAU,GAAG,KAAK;AAEjC,MAAI,OAAO,MAAM,WAChB,OAAM,IAAI,MAAM,eAAe;AAEhC,MAAI,IAAI,SAAS,SAChB,OAAM,IAAI,MAAM,eAAe;EAEhC,IAAI,KAAK;AACT,OAAK,MAAM,QAAQ,SAClB,MAAK,eAAe,GAAG,GAAG;AACzB,UAAO,YAAY,KAAK,CAAC,aAAY,WAAU;AAC9C,WAAO,EAAE,MAAM,MAAM,EAAE;KACtB;;AAGJ,SAAO;;;;;;;;;;;;;;AClCT,eAAsB,eAAe,SAAS,SAAS,SAAS,OAAO;AACtE,QAAO,QAAQ,MAAM,SAAS,MAAM,CAAC,QAAQ,SAAS,QAAQ;;;;;;;;AAW/D,SAAgB,iBAAiB,SAAS,UAAU,SAAS;AAC5D,QAAO,QAAQ,MAAM,QAAQ,CAAC,UAAU,SAAS,SAAS;;;;;;;;;;;;;ACb3D,eAAsB,YAAY,OAAO,SAAS,SAAS,OAAO;AACjE,QAAO,QAAQ,MAAM,SAAS,MAAM,CAAC,QAAQ,OAAO,QAAQ;;;;;;;;AAS7D,SAAgB,SAAS,OAAO,SAAS;AACxC,QAAO,QAAQ,MAAM,QAAQ,CAAC,IAAI,MAAM;;;;;;;;ACdzC,SAAgB,SAAS,MAAM;AAC9B,QAAO,cAAc,SAAS,KAAK"}
@@ -0,0 +1,178 @@
1
+ import { LazyPromise } from "@yongdall/common";
2
+ import { addFinally, createStore, has } from "@yongdall/context";
3
+ import { getModel, useRealm } from "@yongdall/core";
4
+ import { Query } from "@yongdall/model";
5
+ import { loadPluginProfiles } from "@yongdall/plugins";
6
+
7
+ //#region packages/connection/main.mjs
8
+ const allProviders = await LazyPromise.try(async function() {
9
+ /** @type {[string, ProviderProfile[keyof ProviderProfile]][]} */
10
+ const profiles = await Array.fromAsync(loadPluginProfiles("provider", function* (v) {
11
+ yield* v ? Object.entries(v) : [];
12
+ }));
13
+ return Object.assign(Object.create(null), Object.fromEntries(Object.entries(Object.groupBy(profiles, (v) => v[0])).map(([t, v]) => [t, v ? Object.assign(Object.create(null), ...v.map((v) => v[1])) : Object.create(null)])));
14
+ });
15
+ const providerDefinePromise = LazyPromise.try(async function() {
16
+ /** @type {[string, ProviderDefineProfile[keyof ProviderDefineProfile]][]} */
17
+ const profiles = await Array.fromAsync(loadPluginProfiles("providerDefine", function* (v) {
18
+ yield* v ? Object.entries(v) : [];
19
+ }));
20
+ return Object.assign(Object.create(null), Object.fromEntries(profiles));
21
+ });
22
+ const allDefines = await providerDefinePromise;
23
+ /**
24
+ * @type {Record<string, { [K in keyof ProvidersConverted]: Record<string, Promise<ProvidersConverted[K]>>}>}
25
+ */
26
+ let allConnections = Object.create(null);
27
+ /**
28
+ *
29
+ * @template {string} K
30
+ * @param {K} type
31
+ * @param {string} name
32
+ * @param {Realm?} [realm]
33
+ * @param {boolean} [isAlias]
34
+ */
35
+ async function clear(type, name, realm, isAlias) {
36
+ const realmId = (realm || await useRealm()).id;
37
+ const realmConnections = allConnections[realmId];
38
+ if (!realmConnections) return;
39
+ const connections = realmConnections[type];
40
+ if (!connections) return;
41
+ const db = connections[name];
42
+ delete connections[name];
43
+ if (isAlias) return;
44
+ return (await db)?.abort?.();
45
+ }
46
+ async function stop() {
47
+ const oldConnections = allConnections;
48
+ allConnections = Object.create(null);
49
+ for (const realmConnections of Object.values(oldConnections)) for (const connections of Object.values(realmConnections)) for (const db of Object.values(connections)) (await db)?.abort?.();
50
+ }
51
+ /**
52
+ *
53
+ * @template {string} T
54
+ * @param {T} type
55
+ * @param {string} name
56
+ * @param {Realm} realm
57
+ * @returns {Promise<[uri: string, alias?: string]>}
58
+ */
59
+ async function getUri(type, name, realm) {
60
+ if (!name) {
61
+ const provider = realm.providers[type];
62
+ return [typeof provider === "string" && provider || ""];
63
+ }
64
+ const model = await getModel("database");
65
+ if (!model) return [""];
66
+ let sql = new Query(model, true).where("type", type).where("name", name);
67
+ sql = sql.select("uri");
68
+ const aliasField = model.fields.alias;
69
+ if (aliasField && aliasField.type === "string") sql = sql.select("alias");
70
+ using conn = connect("rdb", "", realm);
71
+ const a = await conn.first(sql);
72
+ if (!a) return [""];
73
+ const { uri, alias } = a;
74
+ return [uri || "", alias];
75
+ }
76
+ /**
77
+ *
78
+ * @template {string & keyof Providers} K
79
+ * @param {K} type
80
+ * @param {string} [dbId]
81
+ * @param {Realm?} [realm]
82
+ */
83
+ async function findConnection(type, dbId, realm) {
84
+ const currentRealm = realm || await useRealm();
85
+ const realmId = currentRealm.id;
86
+ let realmConnections = allConnections[realmId];
87
+ if (!realmConnections) {
88
+ realmConnections = Object.create(null);
89
+ allConnections[realmId] = realmConnections;
90
+ }
91
+ /** @type {Record<string, Promise<ProvidersConverted[K]>>} */
92
+ let connections = realmConnections[type];
93
+ if (!connections) {
94
+ connections = Object.create(null);
95
+ realmConnections[type] = connections;
96
+ }
97
+ const dbName = String(dbId || "");
98
+ const connection = connections[dbName];
99
+ if (connection) return connection;
100
+ const providers = allProviders[type];
101
+ if (!providers) throw new Error(`不支持 ${type} 类型`);
102
+ /**
103
+ *
104
+ * @param {string} uri
105
+ * @returns
106
+ */
107
+ async function build(uri) {
108
+ if (!uri) {
109
+ /** @type {ProvidersConverted[K] | Providers[K]} */
110
+ const conn = allDefines[type]?.default;
111
+ if (conn) return conn;
112
+ throw new Error(`找不到 URI (${type}, ${dbName})`);
113
+ }
114
+ const protocol = uri.split(":", 1)[0].split("+", 1)[0].toLowerCase();
115
+ const provider = providers[protocol];
116
+ if (typeof provider !== "function") throw new Error(`不支持 ${protocol} 协议`);
117
+ const promise = await provider(uri);
118
+ /** @type {ProvidersConverted[K] | Providers[K]} */
119
+ const conn = allDefines[type]?.convert?.(promise) || promise;
120
+ if (!conn) throw new Error();
121
+ return conn;
122
+ }
123
+ const conn = getUri(type, dbName, currentRealm).then(([uri, alias]) => {
124
+ if (!alias) return build(uri);
125
+ const connection = connections[alias];
126
+ if (connection) return connection;
127
+ const conn = getUri(type, alias, currentRealm).then(([uri, alias]) => alias ? Promise.reject(/* @__PURE__ */ new Error()) : build(uri));
128
+ connections[alias] = conn;
129
+ return conn;
130
+ });
131
+ connections[dbName] = conn;
132
+ return conn;
133
+ }
134
+ /**
135
+ *
136
+ * @template {string} K
137
+ * @param {K} type
138
+ * @param {string} [dbId]
139
+ * @param {Realm?} [realm]
140
+ * @returns {Connections[K]}
141
+ */
142
+ function connect(type, dbId, realm) {
143
+ const res = allDefines[type]?.connect?.(findConnection(type, dbId, realm));
144
+ if (!res) throw new Error();
145
+ return res;
146
+ }
147
+ const [dbGetter, dbSetter] = createStore(null);
148
+ /**
149
+ * @template {string & keyof ProvidersConverted} T
150
+ * @param {T} type
151
+ * @param {string?} [dbId]
152
+ * @returns {Connections[T]}
153
+ */
154
+ function useConnection(type, dbId) {
155
+ has(true);
156
+ let dbs = dbGetter();
157
+ if (!dbs) {
158
+ dbs = {};
159
+ dbSetter(dbs);
160
+ }
161
+ let typed = dbs[type];
162
+ if (!typed) {
163
+ typed = {};
164
+ dbs[type] = typed;
165
+ }
166
+ const dbName = String(dbId || "");
167
+ if (Object.hasOwn(typed, dbName)) return typed[dbName];
168
+ const db = connect(type, dbName);
169
+ typed[dbName] = db;
170
+ addFinally(() => {
171
+ db.abort?.();
172
+ });
173
+ return db;
174
+ }
175
+
176
+ //#endregion
177
+ export { useConnection as a, stop as i, connect as n, providerDefinePromise as r, clear as t };
178
+ //# sourceMappingURL=main-B_-mso2s.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-B_-mso2s.mjs","names":[],"sources":["../../packages/connection/main.mjs"],"sourcesContent":["import { LazyPromise } from '@yongdall/common';\nimport { addFinally, createStore, has } from '@yongdall/context';\nimport { getModel, useRealm } from '@yongdall/core';\nimport { Query } from '@yongdall/model';\nimport { loadPluginProfiles } from '@yongdall/plugins';\n/** @import { Realm } from '@yongdall/types' */\n\n/** @import {Connections, ProviderDefineProfile, ProviderProfile, Providers, ProvidersConverted} from './types.mjs' */\n\n\n\nconst providerPromise = LazyPromise.try(async function () {\n\t/** @type {[string, ProviderProfile[keyof ProviderProfile]][]} */\n\tconst profiles = await Array.fromAsync(loadPluginProfiles('provider', function *(/** @type {ProviderProfile}*/v) {\n\t\tyield* v ? Object.entries(v) : [];\n\t}));\n\t/** @type {ProviderProfile} */\n\tconst allProviders = Object.assign(Object.create(null), Object.fromEntries(\n\t\tObject.entries(Object.groupBy(profiles, v => v[0])).map(([t, v]) => [\n\t\t\tt, v ? Object.assign(Object.create(null), ...v.map(v => v[1])) : Object.create(null)\n\t\t]),\n\t));\n\treturn allProviders;\n});\n\nconst allProviders = await providerPromise;\n\n\n\nexport const providerDefinePromise = LazyPromise.try(async function () {\n\t/** @type {[string, ProviderDefineProfile[keyof ProviderDefineProfile]][]} */\n\t// @ts-ignore\n\tconst profiles = await Array.fromAsync(loadPluginProfiles('providerDefine', function *(/** @type {ProviderDefineProfile}*/v) {\n\t\tyield* v ? Object.entries(v) : [];\n\t}));\n\t/** @type {ProviderDefineProfile} */\n\tconst allDefines = Object.assign(Object.create(null), Object.fromEntries(profiles));\n\treturn allDefines;\n});\n\nconst allDefines = await providerDefinePromise\n\n\n/**\n * @type {Record<string, { [K in keyof ProvidersConverted]: Record<string, Promise<ProvidersConverted[K]>>}>}\n */\nlet allConnections = Object.create(null);\n/**\n * \n * @template {string} K\n * @param {K} type\n * @param {string} name \n * @param {Realm?} [realm] \n * @param {boolean} [isAlias] \n */\nexport async function clear(type, name, realm, isAlias) {\n\tconst realmId = (realm || await useRealm()).id;\n\tconst realmConnections = allConnections[realmId];\n\tif (!realmConnections) { return; }\n\tconst connections = realmConnections[type];\n\tif (!connections) { return; }\n\tconst db = connections[name];\n\tdelete connections[name];\n\tif (isAlias) { return; }\n\tconst k = await db;\n\treturn k?.abort?.();\n}\nexport async function stop() {\n\tconst oldConnections = allConnections;\n\tallConnections = Object.create(null);\n\tfor (const realmConnections of Object.values(oldConnections)) {\n\t\tfor (const connections of Object.values(realmConnections)) {\n\t\t\tfor (const db of Object.values(connections)) {\n\t\t\t\tconst k = await db;\n\t\t\t\tk?.abort?.();\n\t\t\t}\n\t\t}\n\t}\n\n}\n/**\n * \n * @template {string} T\n * @param {T} type\n * @param {string} name \n * @param {Realm} realm \n * @returns {Promise<[uri: string, alias?: string]>}\n */\nasync function getUri(type, name, realm) {\n\tif (!name) {\n\t\tconst provider = realm.providers[type];\n\t\treturn [typeof provider === 'string' && provider || ''];\n\t}\n\tconst model = await getModel('database');\n\tif (!model) { return ['']; }\n\tconst modelQuery = new Query(model, true);\n\tlet sql = modelQuery.where('type', type).where('name', name);\n\tsql = sql.select('uri');\n\tconst aliasField = model.fields.alias;\n\tif (aliasField && aliasField.type === 'string') { sql = sql.select('alias'); }\n\tusing conn = connect('rdb', '', realm);\n\tconst a = await conn.first(sql);\n\tif (!a) { return ['']; }\n\tconst { uri, alias } = a;\n\treturn [uri || '', alias];\n}\n\n\n/**\n * \n * @template {string & keyof Providers} K\n * @param {K} type\n * @param {string} [dbId] \n * @param {Realm?} [realm] \n */\nasync function findConnection(type, dbId, realm) {\n\tconst currentRealm = realm || await useRealm();\n\tconst realmId = currentRealm.id;\n\tlet realmConnections = allConnections[realmId];\n\tif (!realmConnections) {\n\t\trealmConnections = Object.create(null);\n\t\tallConnections[realmId] = realmConnections;\n\t}\n\t/** @type {Record<string, Promise<ProvidersConverted[K]>>} */\n\tlet connections = realmConnections[type];\n\tif (!connections) {\n\t\tconnections = Object.create(null);\n\t\trealmConnections[type] = connections;\n\t}\n\tconst dbName = String(dbId || '');\n\tconst connection = connections[dbName];\n\tif (connection) { return connection; }\n\tconst providers = allProviders[type];\n\tif (!providers) { throw new Error(`不支持 ${type} 类型`); }\n\t/**\n\t * \n\t * @param {string} uri \n\t * @returns \n\t */\n\tasync function build(uri) {\n\t\tif (!uri) {\n\t\t\t/** @type {ProvidersConverted[K] | Providers[K]} */\n\t\t\tconst conn = allDefines[type]?.default;\n\t\t\tif (conn) { return conn; }\n\t\t\tthrow new Error(`找不到 URI (${type}, ${dbName})`);\n\t\t}\n\t\tconst protocol = uri.split(':', 1)[0].split('+', 1)[0].toLowerCase();\n\t\tconst provider = providers[protocol];\n\t\tif (typeof provider !== 'function') {\n\t\t\tthrow new Error(`不支持 ${protocol} 协议`);\n\t\t}\n\t\tconst promise = await provider(uri);\n\t\t/** @type {ProvidersConverted[K] | Providers[K]} */\n\t\tconst conn = allDefines[type]?.convert?.(promise) || promise;\n\t\tif (!conn) { throw new Error(); }\n\t\treturn conn;\n\t}\n\tconst conn = getUri(type, dbName, currentRealm).then(([uri, alias]) => {\n\t\tif (!alias) { return build(uri); }\n\t\tconst connection = connections[alias];\n\t\tif (connection) { return connection; }\n\t\tconst conn = getUri(type, alias, currentRealm).then(([uri, alias]) => alias ? Promise.reject(new Error) : build(uri));\n\t\tconnections[alias] = conn;\n\t\treturn conn;\n\t});\n\tconnections[dbName] = conn;\n\treturn conn;\n}\n\n/**\n * \n * @template {string} K\n * @param {K} type\n * @param {string} [dbId] \n * @param {Realm?} [realm] \n * @returns {Connections[K]}\n */\nexport function connect(type, dbId, realm) {\n\tconst res = allDefines[type]?.connect?.(findConnection(type, dbId, realm));\n\tif (!res) {\n\t\tthrow new Error();\n\t}\n\treturn res;\n}\n\n\n\nconst [dbGetter, dbSetter] = createStore(/** @type {{ [K in keyof Connections]?: Record<String, Connections[K]>}?} */(null));\n\n/**\n * @template {string & keyof ProvidersConverted} T\n * @param {T} type\n * @param {string?} [dbId]\n * @returns {Connections[T]}\n */\nexport function useConnection(type, dbId) {\n\thas(true);\n\tlet dbs = dbGetter();\n\tif (!dbs) {\n\t\tdbs = {};\n\t\tdbSetter(dbs);\n\t}\n\tlet typed = dbs[type];\n\tif (!typed) {\n\t\ttyped = {};\n\t\tdbs[type] = typed;\n\t}\n\tconst dbName = String(dbId || '');\n\tif (Object.hasOwn(typed, dbName)) {\n\t\treturn typed[dbName];\n\t}\n\tconst db = connect(type, dbName);\n\ttyped[dbName] = db;\n\taddFinally(() => { db.abort?.(); });\n\treturn db;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yongdall/connection",
3
- "version": "0.4.0",
3
+ "version": "0.5.2",
4
4
  "type": "module",
5
5
  "main": "./index.mjs",
6
6
  "exports": {
@@ -11,12 +11,13 @@
11
11
  "author": "",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@yongdall/common": "^0.4.0",
15
- "@yongdall/context": "^0.4.0",
16
- "@yongdall/core": "^0.4.0",
17
- "@yongdall/model": "^0.4.0"
14
+ "@yongdall/common": "^0.5.0",
15
+ "@yongdall/context": "^0.5.0",
16
+ "@yongdall/core": "^0.5.2",
17
+ "@yongdall/model": "^0.5.2",
18
+ "@yongdall/plugins": "^0.5.0"
18
19
  },
19
20
  "devDependencies": {
20
- "@yongdall/types": "^0.4.0"
21
+ "@yongdall/types": "^0.5.2"
21
22
  }
22
23
  }
@@ -0,0 +1,14 @@
1
+ import { r as providerDefinePromise } from "../main-B_-mso2s.mjs";
2
+
3
+ //#region packages/connection/yongdall/enumeration.mjs
4
+ async function connectionType() {
5
+ const allDefines = await providerDefinePromise;
6
+ return Object.entries(allDefines).map(([type, { label }]) => ({
7
+ type,
8
+ label
9
+ }));
10
+ }
11
+
12
+ //#endregion
13
+ export { connectionType };
14
+ //# sourceMappingURL=enumeration.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumeration.mjs","names":[],"sources":["../../../packages/connection/yongdall/enumeration.mjs"],"sourcesContent":["import { providerDefinePromise } from '../main.mjs';\n\nexport async function connectionType() {\n\tconst allDefines = await providerDefinePromise\n\treturn Object.entries(allDefines).map(([type, {label}]) => ({ type, label }));\n}\n"],"mappings":";;;AAEA,eAAsB,iBAAiB;CACtC,MAAM,aAAa,MAAM;AACzB,QAAO,OAAO,QAAQ,WAAW,CAAC,KAAK,CAAC,MAAM,EAAC,cAAa;EAAE;EAAM;EAAO,EAAE"}
@@ -0,0 +1,143 @@
1
+ import { Connection } from "@yongdall/model";
2
+
3
+ //#region packages/connection/yongdall/providerDefine.mjs
4
+ /** @import { ProviderDefineProfile, Providers, ProvidersConverted } from '../types.mjs' */
5
+ /** @type {ProviderDefineProfile['fs']} */
6
+ const fs = {
7
+ label: "文件存储",
8
+ convert: (fs) => fs,
9
+ connect: (fs) => ({
10
+ read: (path) => fs.then((s) => s.read(path)),
11
+ write: (path, data, size) => fs.then((s) => s.write(path, data, size)),
12
+ urlRead: (path, expires) => fs.then((s) => s.urlRead(path, expires)),
13
+ urlWrite: (path, expires) => fs.then((s) => s.urlWrite(path, expires)),
14
+ [Symbol.dispose]() {}
15
+ })
16
+ };
17
+ /** @type {ProviderDefineProfile['mq']} */
18
+ const mq = {
19
+ label: "消息队列",
20
+ convert: (service) => ({
21
+ channels: /* @__PURE__ */ new Map(),
22
+ service,
23
+ abort() {}
24
+ }),
25
+ connect: (param) => ({
26
+ subscribe(channelName, listener) {
27
+ let cancelled = false;
28
+ let cancel = () => {
29
+ cancelled = true;
30
+ };
31
+ param.then(({ channels, service }) => {
32
+ if (cancelled) return;
33
+ let channel = channels.get(channelName);
34
+ if (!channel) {
35
+ /** @type {Set<(val: any) => any>} */
36
+ const listeners = /* @__PURE__ */ new Set();
37
+ channel = {
38
+ listeners,
39
+ promise: Promise.resolve(null),
40
+ run(value) {
41
+ try {
42
+ for (const f of [...listeners]) f(value);
43
+ } catch {}
44
+ }
45
+ };
46
+ channels.set(channelName, channel);
47
+ }
48
+ const listeners = channel.listeners;
49
+ if (!listeners.size) channel.promise = channel.promise.then((v) => v || service.subscribe(channelName, channel.run));
50
+ listeners.add(listener);
51
+ cancel = () => {
52
+ if (cancelled) return;
53
+ cancelled = true;
54
+ listeners.delete(listener);
55
+ if (!listeners.size) {
56
+ const promise = channel.promise;
57
+ channel.promise = promise.then((v) => v?.()).then(() => null);
58
+ }
59
+ };
60
+ });
61
+ return () => {
62
+ cancel();
63
+ };
64
+ },
65
+ async publish(channel, message) {
66
+ const { channels, service } = await param;
67
+ await service.publish(channel, message);
68
+ },
69
+ [Symbol.dispose]() {}
70
+ })
71
+ };
72
+ /** @type {ProviderDefineProfile['tq']} */
73
+ const tq = {
74
+ label: "任务队列",
75
+ convert: (service) => ({
76
+ channels: /* @__PURE__ */ new Map(),
77
+ service,
78
+ abort() {
79
+ service.disconnect();
80
+ }
81
+ }),
82
+ connect: (param) => ({
83
+ async publish(queue, message) {
84
+ const { channels, service } = await param;
85
+ await service.publish(queue, message);
86
+ },
87
+ async get(queue) {
88
+ const { channels, service } = await param;
89
+ const promise = (channels.get(queue) || Promise.resolve()).then(() => service).then((v) => v.get(queue));
90
+ channels.set(queue, promise.catch(() => {}));
91
+ return promise;
92
+ },
93
+ [Symbol.dispose]() {}
94
+ })
95
+ };
96
+ /** @type {ProviderDefineProfile['rdb']} */
97
+ const rdb = {
98
+ label: "关系型数据库",
99
+ convert: (conn) => conn,
100
+ connect: (conn) => new Connection(conn)
101
+ };
102
+ /** @type {ProviderDefineProfile['cache']} */
103
+ const cache = {
104
+ label: "缓存",
105
+ default: {
106
+ set: async (key, field, value) => {},
107
+ get: async (key, field) => {},
108
+ exists: async (key, field) => false,
109
+ del: async (key, field) => {},
110
+ clear: async (key) => {},
111
+ setExpirable: async (key, field, value, ttl) => {},
112
+ getExpirable: async (key, field) => {},
113
+ existsExpirable: async (key, field) => false,
114
+ delExpirable: async (key, field) => {},
115
+ abort() {}
116
+ },
117
+ convert: ({ disconnect, ...cache }) => ({
118
+ ...cache,
119
+ abort: disconnect
120
+ }),
121
+ connect: (cache) => ({
122
+ set: (key, field, value) => cache.then((c) => c.set(key, field, value)),
123
+ get: (key, field) => cache.then((c) => c.get(key, field)),
124
+ exists: (key, field) => cache.then((c) => c.exists(key, field)),
125
+ del: (key, field) => cache.then((c) => c.del(key, field)),
126
+ clear: (key) => cache.then((c) => c.clear(key)),
127
+ setExpirable: (key, field, value, ttl) => cache.then((c) => c.setExpirable(key, field, value, ttl)),
128
+ getExpirable: (key, field) => cache.then((c) => c.getExpirable(key, field)),
129
+ existsExpirable: (key, field) => cache.then((c) => c.existsExpirable(key, field)),
130
+ delExpirable: (key, field) => cache.then((c) => c.delExpirable(key, field)),
131
+ memoize: (key, field, exec) => cache.then((c) => c.get(key, field).then(async (v) => {
132
+ if (v !== void 0) return v;
133
+ const val = await exec();
134
+ await c.set(key, field, val);
135
+ return val;
136
+ })),
137
+ [Symbol.dispose]() {}
138
+ })
139
+ };
140
+
141
+ //#endregion
142
+ export { cache, fs, mq, rdb, tq };
143
+ //# sourceMappingURL=providerDefine.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerDefine.mjs","names":[],"sources":["../../../packages/connection/yongdall/providerDefine.mjs"],"sourcesContent":["import { Connection } from '@yongdall/model';\n/** @import { ProviderDefineProfile, Providers, ProvidersConverted } from '../types.mjs' */\n\n\n/** @type {ProviderDefineProfile['fs']} */\nexport const fs = {\n\tlabel: '文件存储',\n\tconvert: (/** @type {Providers['fs']} */ fs) => fs,\n\tconnect: (/** @type {Promise<ProvidersConverted['fs']>} */ fs) => ({\n\t\tread: path => fs.then(s => s.read(path)),\n\t\twrite: (path, data, size) => fs.then(s => s.write(path, data, size)),\n\t\turlRead: (path, expires) => fs.then(s => s.urlRead(path, expires)),\n\t\turlWrite: (path, expires) => fs.then(s => s.urlWrite(path, expires)),\n\t\t[Symbol.dispose]() { },\n\t}),\n};\n/** @type {ProviderDefineProfile['mq']} */\nexport const mq = {\n\tlabel: '消息队列',\n\tconvert: (/** @type {Providers['mq']} */ service) => /** @type {ProvidersConverted['mq']} */({\n\t\tchannels: new Map(),\n\t\tservice,\n\t\tabort() {\n\t\t\t// TODO: \n\t\t},\n\t}),\n\tconnect: (/** @type {Promise<ProvidersConverted['mq']>} */param) => ({\n\t\t/**\n\t\t * \n\t\t * @param {string} channelName \n\t\t * @param {(val: any) => any} listener \n\t\t */\n\t\tsubscribe(channelName, listener) {\n\t\t\tlet cancelled = false;\n\t\t\tlet cancel = () => { cancelled = true; };\n\t\t\tparam.then(({ channels, service }) => {\n\t\t\t\tif (cancelled) { return; }\n\t\t\t\tlet channel = channels.get(channelName);\n\t\t\t\tif (!channel) {\n\t\t\t\t\t/** @type {Set<(val: any) => any>} */\n\t\t\t\t\tconst listeners = new Set();\n\t\t\t\t\tchannel = {\n\t\t\t\t\t\tlisteners, promise: Promise.resolve(null), run(value) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tfor (const f of [...listeners]) { f(value); }\n\t\t\t\t\t\t\t} catch {\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tchannels.set(channelName, channel);\n\t\t\t\t}\n\n\t\t\t\tconst listeners = channel.listeners;\n\n\t\t\t\tif (!listeners.size) {\n\t\t\t\t\tchannel.promise = channel.promise\n\t\t\t\t\t\t.then(v => v || service.subscribe(channelName, channel.run));\n\t\t\t\t}\n\t\t\t\tlisteners.add(listener);\n\t\t\t\tcancel = () => {\n\t\t\t\t\tif (cancelled) { return; }\n\t\t\t\t\tcancelled = true;\n\t\t\t\t\tlisteners.delete(listener);\n\t\t\t\t\tif (!listeners.size) {\n\t\t\t\t\t\tconst promise = channel.promise;\n\t\t\t\t\t\tchannel.promise = promise.then(v => v?.()).then(() => null);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t});\n\n\t\t\treturn () => { cancel(); };\n\t\t},\n\t\t/**\n\t\t * \n\t\t * @param {string} channel \n\t\t * @param {any} message \n\t\t */\n\t\tasync publish(channel, message) {\n\t\t\tconst { channels, service } = await param;\n\t\t\tawait service.publish(channel, message);\n\t\t},\n\t\t[Symbol.dispose]() { },\n\t}),\n};\n/** @type {ProviderDefineProfile['tq']} */\nexport const tq = {\n\tlabel: '任务队列',\n\tconvert: (/** @type {Providers['tq']} */ service) => /** @type {ProvidersConverted['tq']} */({\n\t\tchannels: new Map(),\n\t\tservice,\n\t\tabort() { service.disconnect(); },\n\t}),\n\tconnect: (/** @type {Promise<ProvidersConverted['tq']>} */param) => ({\n\t\t/**\n\t\t * \n\t\t * @param {string} queue \n\t\t * @param {any} message \n\t\t */\n\t\tasync publish(queue, message) {\n\t\t\tconst { channels, service } = await param;\n\t\t\tawait service.publish(queue, message);\n\t\t},\n\t\t/**\n\t\t * @template T\n\t\t * @param {string} queue \n\t\t * @returns {Promise<T | void>}\n\t\t */\n\t\tasync get(queue) {\n\t\t\tconst { channels, service } = await param;\n\t\t\tconst taskQueueChannel = channels.get(queue) || Promise.resolve();\n\n\t\t\tconst promise = taskQueueChannel\n\t\t\t\t.then(() => service)\n\t\t\t\t.then(v => v.get(queue));\n\n\t\t\tchannels.set(queue, promise.catch(() => { }));\n\t\t\treturn promise;\n\t\t},\n\t\t[Symbol.dispose]() { },\n\t}),\n};\n/** @type {ProviderDefineProfile['rdb']} */\nexport const rdb = {\n\tlabel: '关系型数据库',\n\tconvert: (/** @type {Providers['rdb']} */ conn) => conn,\n\tconnect: (/** @type {Promise<ProvidersConverted['rdb']>} */ conn) => new Connection(conn),\n};\n/** @type {ProviderDefineProfile['cache']} */\nexport const cache = {\n\tlabel: '缓存',\n\tdefault: /** @type {ProvidersConverted['cache']} */({\n\t\tset: async (key, field, value) => { },\n\t\tget: async (key, field) => { },\n\t\texists: async (key, field) => false,\n\t\tdel: async (key, field) => { },\n\t\tclear: async (key) => { },\n\t\tsetExpirable: async (key, field, value, ttl) => { },\n\t\tgetExpirable: async (key, field) => { },\n\t\texistsExpirable: async (key, field) => false,\n\t\tdelExpirable: async (key, field) => { },\n\t\tabort() { },\n\t}),\n\tconvert: (/** @type {Providers['cache']} */ { disconnect, ...cache }) => ({\n\t\t...cache,\n\t\tabort: disconnect,\n\t}),\n\tconnect: (/** @type {Promise<ProvidersConverted['cache']>} */ cache) => ({\n\t\tset: (key, field, value) => cache.then(c => c.set(key, field, value)),\n\t\tget: (key, field) => cache.then(c => c.get(key, field)),\n\t\texists: (key, field) => cache.then(c => c.exists(key, field)),\n\t\tdel: (key, field) => cache.then(c => c.del(key, field)),\n\t\tclear: (key) => cache.then(c => c.clear(key)),\n\t\tsetExpirable: (key, field, value, ttl) => cache.then(c => c.setExpirable(key, field, value, ttl)),\n\t\tgetExpirable: (key, field) => cache.then(c => c.getExpirable(key, field)),\n\t\texistsExpirable: (key, field) => cache.then(c => c.existsExpirable(key, field)),\n\t\tdelExpirable: (key, field) => cache.then(c => c.delExpirable(key, field)),\n\t\tmemoize: (key, field, exec) => cache.then(c => c.get(key, field).then(async (/** @type {*} */v) => {\n\t\t\tif (v !== undefined) { return v; }\n\t\t\tconst val = await exec();\n\t\t\tawait c.set(key, field, val);\n\t\t\treturn val;\n\t\t})),\n\t\t[Symbol.dispose]() { },\n\t}),\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ label: 数据库连接
@@ -1,117 +0,0 @@
1
- import { Connection } from "@yongdall/model";
2
-
3
- //#region packages/connection/hooks.yongdall.mjs
4
- /** @import {Hooks, Providers, ProvidersConverted, Connections} from './types.mjs' */
5
- /** @type {Hooks.providerDefines} */
6
- const providerDefines = {
7
- fs: {
8
- convert: (fs) => fs,
9
- connect: (fs) => ({
10
- read: (path) => fs.then((s) => s.read(path)),
11
- write: (path, data, size) => fs.then((s) => s.write(path, data, size)),
12
- urlRead: (path, expires) => fs.then((s) => s.urlRead(path, expires)),
13
- urlWrite: (path, expires) => fs.then((s) => s.urlWrite(path, expires))
14
- })
15
- },
16
- mq: {
17
- convert: (service) => ({
18
- channels: /* @__PURE__ */ new Map(),
19
- service,
20
- abort() {}
21
- }),
22
- connect: (param) => ({
23
- async subscribe(channelName, listener) {
24
- const { channels, service } = await param;
25
- let channel = channels.get(channelName);
26
- if (!channel) {
27
- /** @type {Set<(val: any) => any>} */
28
- const listeners = /* @__PURE__ */ new Set();
29
- channel = {
30
- listeners,
31
- promise: Promise.resolve(null),
32
- run(value) {
33
- try {
34
- for (const f of [...listeners]) f(value);
35
- } catch {}
36
- }
37
- };
38
- channels.set(channelName, channel);
39
- }
40
- const listeners = channel.listeners;
41
- if (!listeners.size) channel.promise = channel.promise.then((v) => v || service.subscribe(channelName, channel.run));
42
- listeners.add(listener);
43
- let done = false;
44
- return () => {
45
- if (done) return;
46
- done = true;
47
- listeners.delete(listener);
48
- if (!listeners.size) {
49
- const promise = channel.promise;
50
- channel.promise = promise.then((v) => v?.()).then(() => null);
51
- }
52
- };
53
- },
54
- async publish(channel, message) {
55
- const { channels, service } = await param;
56
- await service.publish(channel, message);
57
- }
58
- })
59
- },
60
- tq: {
61
- convert: (service) => ({
62
- channels: /* @__PURE__ */ new Map(),
63
- service,
64
- abort() {
65
- service.disconnect();
66
- }
67
- }),
68
- connect: (param) => ({
69
- async publish(queue, message) {
70
- const { channels, service } = await param;
71
- await service.publish(queue, message);
72
- },
73
- async get(queue) {
74
- const { channels, service } = await param;
75
- const promise = (channels.get(queue) || Promise.resolve()).then(() => service).then((v) => v.get(queue));
76
- channels.set(queue, promise.catch(() => {}));
77
- return promise;
78
- },
79
- abort() {}
80
- })
81
- },
82
- rdb: {
83
- convert: (conn) => conn,
84
- connect: (conn) => new Connection(conn)
85
- },
86
- cache: {
87
- default: {
88
- set: async (key, field, value) => {},
89
- get: async (key, field) => {},
90
- exists: async (key, field) => false,
91
- del: async (key, field) => {},
92
- clear: async (key) => {},
93
- abort() {}
94
- },
95
- convert: ({ disconnect, ...cache }) => ({
96
- ...cache,
97
- abort: disconnect
98
- }),
99
- connect: (cache) => ({
100
- set: (key, field, value) => cache.then((c) => c.set(key, field, value)),
101
- get: (key, field) => cache.then((c) => c.get(key, field)),
102
- exists: (key, field) => cache.then((c) => c.exists(key, field)),
103
- del: (key, field) => cache.then((c) => c.del(key, field)),
104
- clear: (key) => cache.then((c) => c.clear(key)),
105
- memoize: (key, field, exec) => cache.then((c) => c.get(key, field).then(async (v) => {
106
- if (v !== void 0) return v;
107
- const val = await exec();
108
- await c.set(key, field, val);
109
- return val;
110
- }))
111
- })
112
- }
113
- };
114
-
115
- //#endregion
116
- export { providerDefines };
117
- //# sourceMappingURL=hooks.yongdall.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.yongdall.mjs","names":[],"sources":["../../packages/connection/hooks.yongdall.mjs"],"sourcesContent":["import { Connection } from '@yongdall/model';\n/** @import {Hooks, Providers, ProvidersConverted, Connections} from './types.mjs' */\n\n\n/** @type {Hooks.providerDefines} */\nexport const providerDefines = {\n\tfs: {\n\t\tconvert: (/** @type {Providers['fs']} */ fs) => fs,\n\t\tconnect: (/** @type {Promise<ProvidersConverted['fs']>} */ fs) => /** @type {Connections['fs']} */({\n\t\t\tread: path => fs.then(s => s.read(path)),\n\t\t\twrite: (path, data, size) => fs.then(s => s.write(path, data, size)),\n\t\t\turlRead: (path, expires) => fs.then(s => s.urlRead(path, expires)),\n\t\t\turlWrite: (path, expires) => fs.then(s => s.urlWrite(path, expires)),\n\t\t}),\n\t},\n\tmq: {\n\t\tconvert: (/** @type {Providers['mq']} */ service) => /** @type {ProvidersConverted['mq']} */({\n\t\t\tchannels: new Map(),\n\t\t\tservice,\n\t\t\tabort() {\n\t\t\t\t// TODO: \n\t\t\t},\n\t\t}),\n\t\tconnect: (/** @type {Promise<ProvidersConverted['mq']>} */param) => ({\n\t\t\t/**\n\t\t\t * \n\t\t\t * @param {string} channelName \n\t\t\t * @param {(val: any) => any} listener \n\t\t\t */\n\t\t\tasync subscribe(channelName, listener) {\n\t\t\t\tconst { channels, service } = await param;\n\t\t\t\tlet channel = channels.get(channelName);\n\t\t\t\tif (!channel) {\n\t\t\t\t\t/** @type {Set<(val: any) => any>} */\n\t\t\t\t\tconst listeners = new Set();\n\t\t\t\t\tchannel = {\n\t\t\t\t\t\tlisteners, promise: Promise.resolve(null), run(value) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tfor (const f of [...listeners]) { f(value); }\n\t\t\t\t\t\t\t} catch {\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tchannels.set(channelName, channel);\n\t\t\t\t}\n\n\t\t\t\tconst listeners = channel.listeners;\n\n\t\t\t\tif (!listeners.size) {\n\t\t\t\t\tchannel.promise = channel.promise\n\t\t\t\t\t\t.then(v => v || service.subscribe(channelName, channel.run));\n\t\t\t\t}\n\t\t\t\tlisteners.add(listener);\n\n\t\t\t\tlet done = false;\n\t\t\t\treturn () => {\n\t\t\t\t\tif (done) { return; }\n\t\t\t\t\tdone = true;\n\t\t\t\t\tlisteners.delete(listener);\n\t\t\t\t\tif (!listeners.size) {\n\n\t\t\t\t\t\tconst promise = channel.promise;\n\t\t\t\t\t\tchannel.promise = promise.then(v => v?.()).then(() => null);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\t\t\t/**\n\t\t\t * \n\t\t\t * @param {string} channel \n\t\t\t * @param {any} message \n\t\t\t */\n\t\t\tasync publish(channel, message) {\n\t\t\t\tconst { channels, service } = await param;\n\t\t\t\tawait service.publish(channel, message);\n\t\t\t},\n\t\t}),\n\t},\n\ttq: {\n\t\tconvert: (/** @type {Providers['tq']} */ service) => /** @type {ProvidersConverted['tq']} */({\n\t\t\tchannels: new Map(),\n\t\t\tservice,\n\t\t\tabort() { service.disconnect(); },\n\t\t}),\n\t\tconnect: (/** @type {Promise<ProvidersConverted['tq']>} */param) => ({\n\t\t\t/**\n\t\t\t * \n\t\t\t * @param {string} queue \n\t\t\t * @param {any} message \n\t\t\t */\n\t\t\tasync publish(queue, message) {\n\t\t\t\tconst { channels, service } = await param;\n\t\t\t\tawait service.publish(queue, message);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @template T\n\t\t\t * @param {string} queue \n\t\t\t * @returns {Promise<T | void>}\n\t\t\t */\n\t\t\tasync get(queue) {\n\t\t\t\tconst { channels, service } = await param;\n\t\t\t\tconst taskQueueChannel = channels.get(queue) || Promise.resolve();\n\n\t\t\t\tconst promise = taskQueueChannel\n\t\t\t\t\t.then(() => service)\n\t\t\t\t\t.then(v => v.get(queue));\n\n\t\t\t\tchannels.set(queue, promise.catch(() => { }));\n\t\t\t\treturn promise;\n\t\t\t},\n\t\t\tabort() { },\n\t\t}),\n\t},\n\trdb: {\n\t\tconvert: (/** @type {Providers['rdb']} */ conn) => conn,\n\t\tconnect: (/** @type {Promise<ProvidersConverted['rdb']>} */ conn) => new Connection(conn),\n\t},\n\tcache: {\n\t\tdefault: /** @type {ProvidersConverted['cache']} */({\n\t\t\tset: async (key, field, value) => { },\n\t\t\tget: async (key, field) => { },\n\t\t\texists: async (key, field) => false,\n\t\t\tdel: async (key, field) => { },\n\t\t\tclear: async (key) => { },\n\t\t\tabort() { },\n\t\t}),\n\t\tconvert: (/** @type {Providers['cache']} */ { disconnect, ...cache }) => ({\n\t\t\t...cache,\n\t\t\tabort: disconnect,\n\t\t}),\n\t\tconnect: (/** @type {Promise<ProvidersConverted['cache']>} */ cache) => /** @type {Connections['cache']} */({\n\t\t\tset: (key, field, value) => cache.then(c => c.set(key, field, value)),\n\t\t\tget: (key, field) => cache.then(c => c.get(key, field)),\n\t\t\texists: (key, field) => cache.then(c => c.exists(key, field)),\n\t\t\tdel: (key, field) => cache.then(c => c.del(key, field)),\n\t\t\tclear: (key) => cache.then(c => c.clear(key)),\n\t\t\tmemoize: (key, field, exec) => cache.then(c => c.get(key, field).then(async v => {\n\t\t\t\tif (v !== undefined) { return v; }\n\t\t\t\tconst val = await exec();\n\t\t\t\tawait c.set(key, field, val);\n\t\t\t\treturn val;\n\t\t\t}))\n\t\t}),\n\t},\n};\n"],"mappings":"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"}