@yongdall/connection 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.mts +64 -45
- package/index.mjs +11 -178
- package/index.mjs.map +1 -1
- package/main-C8igejll.mjs +177 -0
- package/main-C8igejll.mjs.map +1 -0
- package/package.json +7 -6
- package/yongdall/enumeration.mjs +14 -0
- package/yongdall/enumeration.mjs.map +1 -0
- package/yongdall/providerDefine.mjs +140 -0
- package/yongdall/providerDefine.mjs.map +1 -0
- package/yongdall.plugin.yml +1 -0
- package/hooks.yongdall.mjs +0 -117
- package/hooks.yongdall.mjs.map +0 -1
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 { Tenant } 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]
|
|
@@ -79,6 +51,52 @@ 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
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region packages/connection/main.d.mts
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @template {string} K
|
|
76
|
+
* @param {K} type
|
|
77
|
+
* @param {string} name
|
|
78
|
+
* @param {Tenant?} [tenant]
|
|
79
|
+
* @param {boolean} [isAlias]
|
|
80
|
+
*/
|
|
81
|
+
declare function clear<K extends string>(type: K, name: string, tenant?: Tenant | null, isAlias?: boolean): Promise<void>;
|
|
82
|
+
declare function stop(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @template {string} K
|
|
86
|
+
* @param {K} type
|
|
87
|
+
* @param {string} [dbId]
|
|
88
|
+
* @param {Tenant?} [tenant]
|
|
89
|
+
* @returns {Connections[K]}
|
|
90
|
+
*/
|
|
91
|
+
declare function connect<K extends string>(type: K, dbId?: string, tenant?: Tenant | null): Connections[K];
|
|
92
|
+
/**
|
|
93
|
+
* @template {string & keyof ProvidersConverted} T
|
|
94
|
+
* @param {T} type
|
|
95
|
+
* @param {string?} [dbId]
|
|
96
|
+
* @returns {Connections[T]}
|
|
97
|
+
*/
|
|
98
|
+
declare function useConnection<T extends string & keyof ProvidersConverted>(type: T, dbId?: string | null): Connections[T];
|
|
99
|
+
//#endregion
|
|
82
100
|
//#region packages/connection/types.d.mts
|
|
83
101
|
type Provider<T> = (uri: string) => T | PromiseLike<T>;
|
|
84
102
|
interface MessageQueue {
|
|
@@ -96,6 +114,10 @@ interface Cache {
|
|
|
96
114
|
exists(key: string, field: string): PromiseLike<boolean> | boolean;
|
|
97
115
|
del(key: string, field: string): PromiseLike<void> | void;
|
|
98
116
|
clear(key: string): PromiseLike<void> | void;
|
|
117
|
+
setExpirable(key: string, field: string, value: any, ttl: number): PromiseLike<void> | void;
|
|
118
|
+
getExpirable<T>(key: string, field: string): PromiseLike<T | void> | T | void;
|
|
119
|
+
existsExpirable(key: string, field: string): PromiseLike<boolean> | boolean;
|
|
120
|
+
delExpirable(key: string, field: string): PromiseLike<void> | void;
|
|
99
121
|
disconnect(): void;
|
|
100
122
|
}
|
|
101
123
|
interface FileStore {
|
|
@@ -162,6 +184,10 @@ interface Connections {
|
|
|
162
184
|
exists(key: string, field: string): PromiseLike<boolean>;
|
|
163
185
|
del(key: string, field: string): PromiseLike<void>;
|
|
164
186
|
clear(key: string): PromiseLike<void>;
|
|
187
|
+
setExpirable(key: string, field: string, value: any, ttl: number): PromiseLike<void>;
|
|
188
|
+
getExpirable<T>(key: string, field: string): PromiseLike<T | void>;
|
|
189
|
+
existsExpirable(key: string, field: string): PromiseLike<boolean>;
|
|
190
|
+
delExpirable(key: string, field: string): PromiseLike<void>;
|
|
165
191
|
memoize<T>(key: string, field: string, exec: () => PromiseLike<T> | T): PromiseLike<T>;
|
|
166
192
|
abort?(): void;
|
|
167
193
|
};
|
|
@@ -169,19 +195,12 @@ interface Connections {
|
|
|
169
195
|
abort?(): void;
|
|
170
196
|
};
|
|
171
197
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
}
|
|
198
|
+
type ProviderProfile = { [K in keyof Providers]: Record<string, Provider<Providers[K]>> };
|
|
199
|
+
type ProviderDefineProfile = { [K in keyof ProvidersConverted]: {
|
|
200
|
+
label: string;
|
|
201
|
+
convert: (vla: Providers[K]) => MaybePromise<ProvidersConverted[K]>;
|
|
202
|
+
connect: (vla: Promise<ProvidersConverted[K]>) => Connections[K];
|
|
203
|
+
default?: ProvidersConverted[K];
|
|
204
|
+
} };
|
|
186
205
|
//#endregion
|
|
187
|
-
export { Cache, Connections, FileStore,
|
|
206
|
+
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 {
|
|
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-C8igejll.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]
|
|
@@ -258,5 +82,14 @@ function waitTask(queue, service) {
|
|
|
258
82
|
}
|
|
259
83
|
|
|
260
84
|
//#endregion
|
|
261
|
-
|
|
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 { 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","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,QAAQ;AACvE,QAAO,QAAQ,MAAM,SAAS,OAAO,CAAC,QAAQ,SAAS,QAAQ;;;;;;;;AAWhE,SAAgB,iBAAiB,SAAS,UAAU,SAAS;AAC5D,QAAO,QAAQ,MAAM,QAAQ,CAAC,UAAU,SAAS,SAAS;;;;;;;;;;;;;ACb3D,eAAsB,YAAY,OAAO,SAAS,SAAS,QAAQ;AAClE,QAAO,QAAQ,MAAM,SAAS,OAAO,CAAC,QAAQ,OAAO,QAAQ;;;;;;;;AAS9D,SAAgB,SAAS,OAAO,SAAS;AACxC,QAAO,QAAQ,MAAM,QAAQ,CAAC,IAAI,MAAM;;;;;;;;ACdzC,SAAgB,SAAS,MAAM;AAC9B,QAAO,cAAc,SAAS,KAAK"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { LazyPromise } from "@yongdall/common";
|
|
2
|
+
import { addFinally, createStore, has } from "@yongdall/context";
|
|
3
|
+
import { getModel, useTenant } 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 {Tenant?} [tenant]
|
|
33
|
+
* @param {boolean} [isAlias]
|
|
34
|
+
*/
|
|
35
|
+
async function clear(type, name, tenant, isAlias) {
|
|
36
|
+
const tenantId = (tenant || await useTenant()).id;
|
|
37
|
+
const tenantConnections = allConnections[tenantId];
|
|
38
|
+
if (!tenantConnections) return;
|
|
39
|
+
const connections = tenantConnections[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 tenantConnections of Object.values(oldConnections)) for (const connections of Object.values(tenantConnections)) 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 {Tenant} tenant
|
|
57
|
+
* @returns {Promise<[uri: string, alias?: string]>}
|
|
58
|
+
*/
|
|
59
|
+
async function getUri(type, name, tenant) {
|
|
60
|
+
if (!name) {
|
|
61
|
+
const provider = tenant.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
|
+
const a = await connect("rdb", "", tenant).first(sql);
|
|
71
|
+
if (!a) return [""];
|
|
72
|
+
const { uri, alias } = a;
|
|
73
|
+
return [uri || "", alias];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @template {string & keyof Providers} K
|
|
78
|
+
* @param {K} type
|
|
79
|
+
* @param {string} [dbId]
|
|
80
|
+
* @param {Tenant?} [tenant]
|
|
81
|
+
*/
|
|
82
|
+
async function findConnection(type, dbId, tenant) {
|
|
83
|
+
const currentTenant = tenant || await useTenant();
|
|
84
|
+
const tenantId = currentTenant.id;
|
|
85
|
+
let tenantConnections = allConnections[tenantId];
|
|
86
|
+
if (!tenantConnections) {
|
|
87
|
+
tenantConnections = Object.create(null);
|
|
88
|
+
allConnections[tenantId] = tenantConnections;
|
|
89
|
+
}
|
|
90
|
+
/** @type {Record<string, Promise<ProvidersConverted[K]>>} */
|
|
91
|
+
let connections = tenantConnections[type];
|
|
92
|
+
if (!connections) {
|
|
93
|
+
connections = Object.create(null);
|
|
94
|
+
tenantConnections[type] = connections;
|
|
95
|
+
}
|
|
96
|
+
const dbName = String(dbId || "");
|
|
97
|
+
const connection = connections[dbName];
|
|
98
|
+
if (connection) return connection;
|
|
99
|
+
const providers = allProviders[type];
|
|
100
|
+
if (!providers) throw new Error(`不支持 ${type} 类型`);
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @param {string} uri
|
|
104
|
+
* @returns
|
|
105
|
+
*/
|
|
106
|
+
async function build(uri) {
|
|
107
|
+
if (!uri) {
|
|
108
|
+
/** @type {ProvidersConverted[K] | Providers[K]} */
|
|
109
|
+
const conn = allDefines[type]?.default;
|
|
110
|
+
if (conn) return conn;
|
|
111
|
+
throw new Error(`找不到 URI (${type}, ${dbName})`);
|
|
112
|
+
}
|
|
113
|
+
const protocol = uri.split(":", 1)[0].split("+", 1)[0].toLowerCase();
|
|
114
|
+
const provider = providers[protocol];
|
|
115
|
+
if (typeof provider !== "function") throw new Error(`不支持 ${protocol} 协议`);
|
|
116
|
+
const promise = await provider(uri);
|
|
117
|
+
/** @type {ProvidersConverted[K] | Providers[K]} */
|
|
118
|
+
const conn = allDefines[type]?.convert?.(promise) || promise;
|
|
119
|
+
if (!conn) throw new Error();
|
|
120
|
+
return conn;
|
|
121
|
+
}
|
|
122
|
+
const conn = getUri(type, dbName, currentTenant).then(([uri, alias]) => {
|
|
123
|
+
if (!alias) return build(uri);
|
|
124
|
+
const connection = connections[alias];
|
|
125
|
+
if (connection) return connection;
|
|
126
|
+
const conn = getUri(type, alias, currentTenant).then(([uri, alias]) => alias ? Promise.reject(/* @__PURE__ */ new Error()) : build(uri));
|
|
127
|
+
connections[alias] = conn;
|
|
128
|
+
return conn;
|
|
129
|
+
});
|
|
130
|
+
connections[dbName] = conn;
|
|
131
|
+
return conn;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
*
|
|
135
|
+
* @template {string} K
|
|
136
|
+
* @param {K} type
|
|
137
|
+
* @param {string} [dbId]
|
|
138
|
+
* @param {Tenant?} [tenant]
|
|
139
|
+
* @returns {Connections[K]}
|
|
140
|
+
*/
|
|
141
|
+
function connect(type, dbId, tenant) {
|
|
142
|
+
const res = allDefines[type]?.connect?.(findConnection(type, dbId, tenant));
|
|
143
|
+
if (!res) throw new Error();
|
|
144
|
+
return res;
|
|
145
|
+
}
|
|
146
|
+
const [dbGetter, dbSetter] = createStore(null);
|
|
147
|
+
/**
|
|
148
|
+
* @template {string & keyof ProvidersConverted} T
|
|
149
|
+
* @param {T} type
|
|
150
|
+
* @param {string?} [dbId]
|
|
151
|
+
* @returns {Connections[T]}
|
|
152
|
+
*/
|
|
153
|
+
function useConnection(type, dbId) {
|
|
154
|
+
has(true);
|
|
155
|
+
let dbs = dbGetter();
|
|
156
|
+
if (!dbs) {
|
|
157
|
+
dbs = {};
|
|
158
|
+
dbSetter(dbs);
|
|
159
|
+
}
|
|
160
|
+
let typed = dbs[type];
|
|
161
|
+
if (!typed) {
|
|
162
|
+
typed = {};
|
|
163
|
+
dbs[type] = typed;
|
|
164
|
+
}
|
|
165
|
+
const dbName = String(dbId || "");
|
|
166
|
+
if (Object.hasOwn(typed, dbName)) return typed[dbName];
|
|
167
|
+
const db = connect(type, dbName);
|
|
168
|
+
typed[dbName] = db;
|
|
169
|
+
addFinally(() => {
|
|
170
|
+
db.abort?.();
|
|
171
|
+
});
|
|
172
|
+
return db;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
//#endregion
|
|
176
|
+
export { useConnection as a, stop as i, connect as n, providerDefinePromise as r, clear as t };
|
|
177
|
+
//# sourceMappingURL=main-C8igejll.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main-C8igejll.mjs","names":[],"sources":["../../packages/connection/main.mjs"],"sourcesContent":["import { LazyPromise } from '@yongdall/common';\nimport { addFinally, createStore, has } from '@yongdall/context';\nimport { getModel, useTenant, hooks } from '@yongdall/core';\nimport { Query } from '@yongdall/model';\nimport { loadPluginProfiles } from '@yongdall/plugins';\n/** @import { Tenant } 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 {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"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yongdall/connection",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
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.
|
|
15
|
-
"@yongdall/context": "^0.
|
|
16
|
-
"@yongdall/core": "^0.
|
|
17
|
-
"@yongdall/model": "^0.
|
|
14
|
+
"@yongdall/common": "^0.5.0",
|
|
15
|
+
"@yongdall/context": "^0.5.0",
|
|
16
|
+
"@yongdall/core": "^0.5.0",
|
|
17
|
+
"@yongdall/model": "^0.5.0",
|
|
18
|
+
"@yongdall/plugins": "^0.5.0"
|
|
18
19
|
},
|
|
19
20
|
"devDependencies": {
|
|
20
|
-
"@yongdall/types": "^0.
|
|
21
|
+
"@yongdall/types": "^0.5.0"
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { r as providerDefinePromise } from "../main-C8igejll.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,140 @@
|
|
|
1
|
+
import { Connection } from "@yongdall/model";
|
|
2
|
+
|
|
3
|
+
//#region packages/connection/yongdall/providerDefine.mjs
|
|
4
|
+
/** @import {ProviderDefineProfile, Providers, ProvidersConverted, Connections} 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
|
+
})
|
|
15
|
+
};
|
|
16
|
+
/** @type {ProviderDefineProfile['mq']} */
|
|
17
|
+
const mq = {
|
|
18
|
+
label: "消息队列",
|
|
19
|
+
convert: (service) => ({
|
|
20
|
+
channels: /* @__PURE__ */ new Map(),
|
|
21
|
+
service,
|
|
22
|
+
abort() {}
|
|
23
|
+
}),
|
|
24
|
+
connect: (param) => ({
|
|
25
|
+
subscribe(channelName, listener) {
|
|
26
|
+
let cancelled = false;
|
|
27
|
+
let cancel = () => {
|
|
28
|
+
cancelled = true;
|
|
29
|
+
};
|
|
30
|
+
param.then(({ channels, service }) => {
|
|
31
|
+
if (cancelled) return;
|
|
32
|
+
let channel = channels.get(channelName);
|
|
33
|
+
if (!channel) {
|
|
34
|
+
/** @type {Set<(val: any) => any>} */
|
|
35
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
36
|
+
channel = {
|
|
37
|
+
listeners,
|
|
38
|
+
promise: Promise.resolve(null),
|
|
39
|
+
run(value) {
|
|
40
|
+
try {
|
|
41
|
+
for (const f of [...listeners]) f(value);
|
|
42
|
+
} catch {}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
channels.set(channelName, channel);
|
|
46
|
+
}
|
|
47
|
+
const listeners = channel.listeners;
|
|
48
|
+
if (!listeners.size) channel.promise = channel.promise.then((v) => v || service.subscribe(channelName, channel.run));
|
|
49
|
+
listeners.add(listener);
|
|
50
|
+
cancel = () => {
|
|
51
|
+
if (cancelled) return;
|
|
52
|
+
cancelled = true;
|
|
53
|
+
listeners.delete(listener);
|
|
54
|
+
if (!listeners.size) {
|
|
55
|
+
const promise = channel.promise;
|
|
56
|
+
channel.promise = promise.then((v) => v?.()).then(() => null);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
return () => {
|
|
61
|
+
cancel();
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
async publish(channel, message) {
|
|
65
|
+
const { channels, service } = await param;
|
|
66
|
+
await service.publish(channel, message);
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
/** @type {ProviderDefineProfile['tq']} */
|
|
71
|
+
const tq = {
|
|
72
|
+
label: "任务队列",
|
|
73
|
+
convert: (service) => ({
|
|
74
|
+
channels: /* @__PURE__ */ new Map(),
|
|
75
|
+
service,
|
|
76
|
+
abort() {
|
|
77
|
+
service.disconnect();
|
|
78
|
+
}
|
|
79
|
+
}),
|
|
80
|
+
connect: (param) => ({
|
|
81
|
+
async publish(queue, message) {
|
|
82
|
+
const { channels, service } = await param;
|
|
83
|
+
await service.publish(queue, message);
|
|
84
|
+
},
|
|
85
|
+
async get(queue) {
|
|
86
|
+
const { channels, service } = await param;
|
|
87
|
+
const promise = (channels.get(queue) || Promise.resolve()).then(() => service).then((v) => v.get(queue));
|
|
88
|
+
channels.set(queue, promise.catch(() => {}));
|
|
89
|
+
return promise;
|
|
90
|
+
},
|
|
91
|
+
abort() {}
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
/** @type {ProviderDefineProfile['rdb']} */
|
|
95
|
+
const rdb = {
|
|
96
|
+
label: "关系型数据库",
|
|
97
|
+
convert: (conn) => conn,
|
|
98
|
+
connect: (conn) => new Connection(conn)
|
|
99
|
+
};
|
|
100
|
+
/** @type {ProviderDefineProfile['cache']} */
|
|
101
|
+
const cache = {
|
|
102
|
+
label: "缓存",
|
|
103
|
+
default: {
|
|
104
|
+
set: async (key, field, value) => {},
|
|
105
|
+
get: async (key, field) => {},
|
|
106
|
+
exists: async (key, field) => false,
|
|
107
|
+
del: async (key, field) => {},
|
|
108
|
+
clear: async (key) => {},
|
|
109
|
+
setExpirable: async (key, field, value, ttl) => {},
|
|
110
|
+
getExpirable: async (key, field) => {},
|
|
111
|
+
existsExpirable: async (key, field) => false,
|
|
112
|
+
delExpirable: async (key, field) => {},
|
|
113
|
+
abort() {}
|
|
114
|
+
},
|
|
115
|
+
convert: ({ disconnect, ...cache }) => ({
|
|
116
|
+
...cache,
|
|
117
|
+
abort: disconnect
|
|
118
|
+
}),
|
|
119
|
+
connect: (cache) => ({
|
|
120
|
+
set: (key, field, value) => cache.then((c) => c.set(key, field, value)),
|
|
121
|
+
get: (key, field) => cache.then((c) => c.get(key, field)),
|
|
122
|
+
exists: (key, field) => cache.then((c) => c.exists(key, field)),
|
|
123
|
+
del: (key, field) => cache.then((c) => c.del(key, field)),
|
|
124
|
+
clear: (key) => cache.then((c) => c.clear(key)),
|
|
125
|
+
setExpirable: (key, field, value, ttl) => cache.then((c) => c.setExpirable(key, field, value, ttl)),
|
|
126
|
+
getExpirable: (key, field) => cache.then((c) => c.getExpirable(key, field)),
|
|
127
|
+
existsExpirable: (key, field) => cache.then((c) => c.existsExpirable(key, field)),
|
|
128
|
+
delExpirable: (key, field) => cache.then((c) => c.delExpirable(key, field)),
|
|
129
|
+
memoize: (key, field, exec) => cache.then((c) => c.get(key, field).then(async (v) => {
|
|
130
|
+
if (v !== void 0) return v;
|
|
131
|
+
const val = await exec();
|
|
132
|
+
await c.set(key, field, val);
|
|
133
|
+
return val;
|
|
134
|
+
}))
|
|
135
|
+
})
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
export { cache, fs, mq, rdb, tq };
|
|
140
|
+
//# 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, Connections} 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) => /** @type {Connections['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}),\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}),\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\tabort() { },\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) => /** @type {Connections['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}),\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
label: 数据库连接
|
package/hooks.yongdall.mjs
DELETED
|
@@ -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
|
package/hooks.yongdall.mjs.map
DELETED
|
@@ -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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"}
|