@akanjs/signal 0.0.53 → 0.0.55

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.mjs ADDED
@@ -0,0 +1 @@
1
+ export * from "./src";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/signal",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "type": "commonjs",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -20,5 +20,11 @@
20
20
  "next": "^15.3.2",
21
21
  "reflect-metadata": "^0.2.2",
22
22
  "socket.io-client": "^4.8.1"
23
+ },
24
+ "exports": {
25
+ ".": {
26
+ "require": "./index.js",
27
+ "import": "./index.mjs"
28
+ }
23
29
  }
24
30
  }
@@ -0,0 +1,15 @@
1
+ import { client } from "./client";
2
+ const nativeFetch = fetch;
3
+ const baseFetch = Object.assign(nativeFetch, {
4
+ client,
5
+ clone: function(option = {}) {
6
+ return {
7
+ ...this,
8
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
9
+ client: this.client.clone(option)
10
+ };
11
+ }
12
+ });
13
+ export {
14
+ baseFetch
15
+ };
package/src/client.mjs ADDED
@@ -0,0 +1,145 @@
1
+ import { baseClientEnv, baseEnv } from "@akanjs/base";
2
+ import { Logger, sleep } from "@akanjs/common";
3
+ import { cacheExchange, createClient, fetchExchange } from "@urql/core";
4
+ import { io } from "socket.io-client";
5
+ class SocketIo {
6
+ socket;
7
+ roomSubscribeMap = /* @__PURE__ */ new Map();
8
+ constructor(uri) {
9
+ this.socket = io(uri, { transports: ["websocket"] });
10
+ this.socket.on("connect", () => {
11
+ this.roomSubscribeMap.forEach((option) => {
12
+ this.socket.emit(option.key, { ...option.message, __subscribe__: true });
13
+ });
14
+ });
15
+ }
16
+ on(event, callback) {
17
+ this.socket.on(event, callback);
18
+ }
19
+ removeListener(event, callback) {
20
+ this.socket.removeListener(event, callback);
21
+ }
22
+ removeAllListeners() {
23
+ this.socket.removeAllListeners();
24
+ }
25
+ hasListeners(event) {
26
+ return this.socket.hasListeners(event);
27
+ }
28
+ emit(key, data) {
29
+ this.socket.emit(key, data);
30
+ }
31
+ subscribe(option) {
32
+ if (!this.roomSubscribeMap.has(option.roomId)) {
33
+ this.roomSubscribeMap.set(option.roomId, option);
34
+ this.socket.emit(option.key, { ...option.message, __subscribe__: true });
35
+ }
36
+ this.socket.on(option.roomId, option.handleEvent);
37
+ }
38
+ unsubscribe(roomId, handleEvent) {
39
+ this.socket.removeListener(roomId, handleEvent);
40
+ const option = this.roomSubscribeMap.get(roomId);
41
+ if (this.hasListeners(roomId) || !option)
42
+ return;
43
+ this.roomSubscribeMap.delete(roomId);
44
+ this.socket.emit(option.key, { ...option.message, __subscribe__: false });
45
+ }
46
+ disconnect() {
47
+ this.socket.disconnect();
48
+ return this;
49
+ }
50
+ }
51
+ class Client {
52
+ static globalIoMap = /* @__PURE__ */ new Map();
53
+ static tokenStore = /* @__PURE__ */ new Map();
54
+ async waitUntilWebSocketConnected(ws = baseClientEnv.serverWsUri) {
55
+ if (baseClientEnv.side === "server")
56
+ return true;
57
+ while (!this.getIo(ws).socket.connected) {
58
+ Logger.verbose("waiting for websocket to initialize...");
59
+ await sleep(300);
60
+ }
61
+ }
62
+ isInitialized = false;
63
+ uri = baseClientEnv.serverGraphqlUri;
64
+ ws = baseClientEnv.serverWsUri;
65
+ udp = null;
66
+ gql = createClient({ url: this.uri, fetch, exchanges: [cacheExchange, fetchExchange] });
67
+ jwt = null;
68
+ async getJwt() {
69
+ const isNextServer = baseClientEnv.side === "server" && baseEnv.operationType === "client";
70
+ if (isNextServer) {
71
+ const nextHeaders = require("next/headers");
72
+ return (await nextHeaders.cookies?.())?.get("jwt")?.value ?? (await nextHeaders.headers?.())?.get("jwt") ?? this.jwt ?? null;
73
+ } else
74
+ return Client.tokenStore.get(this) ?? null;
75
+ }
76
+ io = null;
77
+ init(data = {}) {
78
+ Object.assign(this, data);
79
+ this.setLink(data.uri);
80
+ this.setIo(data.ws);
81
+ this.isInitialized = true;
82
+ }
83
+ setIo(ws = baseClientEnv.serverWsUri) {
84
+ this.ws = ws;
85
+ const existingIo = Client.globalIoMap.get(ws);
86
+ if (existingIo) {
87
+ this.io = existingIo;
88
+ return;
89
+ }
90
+ this.io = new SocketIo(ws);
91
+ Client.globalIoMap.set(ws, this.io);
92
+ }
93
+ getIo(ws = baseClientEnv.serverWsUri) {
94
+ const existingIo = Client.globalIoMap.get(ws);
95
+ if (existingIo)
96
+ return existingIo;
97
+ const io2 = new SocketIo(ws);
98
+ Client.globalIoMap.set(ws, io2);
99
+ return io2;
100
+ }
101
+ setLink(uri = baseClientEnv.serverGraphqlUri) {
102
+ this.uri = uri;
103
+ this.gql = createClient({
104
+ url: this.uri,
105
+ fetch,
106
+ exchanges: [cacheExchange, fetchExchange],
107
+ // requestPolicy: "network-only",
108
+ fetchOptions: () => {
109
+ return {
110
+ headers: {
111
+ "apollo-require-preflight": "true",
112
+ ...this.jwt ? { authorization: `Bearer ${this.jwt}` } : {}
113
+ }
114
+ };
115
+ }
116
+ });
117
+ }
118
+ setJwt(jwt) {
119
+ Client.tokenStore.set(this, jwt);
120
+ }
121
+ reset() {
122
+ this.io?.disconnect();
123
+ this.io = null;
124
+ this.jwt = null;
125
+ }
126
+ clone(data = {}) {
127
+ const newClient = new Client();
128
+ newClient.init({ ...this, ...data });
129
+ if (data.jwt)
130
+ Client.tokenStore.set(newClient, data.jwt);
131
+ return newClient;
132
+ }
133
+ terminate() {
134
+ this.reset();
135
+ Client.globalIoMap.forEach((io2) => io2.disconnect());
136
+ this.isInitialized = false;
137
+ }
138
+ setUdp(udp) {
139
+ this.udp = udp;
140
+ }
141
+ }
142
+ const client = new Client();
143
+ export {
144
+ client
145
+ };
package/src/doc.mjs ADDED
@@ -0,0 +1,82 @@
1
+ import { arraiedModel, getNonArrayModel, isGqlScalar, JSON as GqlJSON } from "@akanjs/base";
2
+ import { getFieldMetas, getScalarExample } from "@akanjs/constant";
3
+ import { getArgMetas, getGqlMeta } from "./signalDecorators";
4
+ class ResponseExampleStorage {
5
+ }
6
+ const getPredefinedRequestExample = (modelRef) => {
7
+ return Reflect.getMetadata(modelRef, ResponseExampleStorage.prototype);
8
+ };
9
+ const getPredefinedResponseExample = (modelRef) => {
10
+ return Reflect.getMetadata(modelRef, ResponseExampleStorage.prototype);
11
+ };
12
+ const getResponseExample = (ref) => {
13
+ const [modelRef, arrDepth] = getNonArrayModel(ref);
14
+ const existing = getPredefinedRequestExample(modelRef);
15
+ if (existing)
16
+ return existing;
17
+ const isScalar = isGqlScalar(modelRef);
18
+ if (isScalar)
19
+ return arraiedModel(getScalarExample(modelRef), arrDepth);
20
+ const fieldMetas = getFieldMetas(modelRef);
21
+ const example = {};
22
+ fieldMetas.forEach((fieldMeta) => {
23
+ if (fieldMeta.example)
24
+ example[fieldMeta.key] = fieldMeta.example;
25
+ else if (fieldMeta.enum)
26
+ example[fieldMeta.key] = arraiedModel(fieldMeta.enum.values[0], fieldMeta.arrDepth);
27
+ else
28
+ example[fieldMeta.key] = getResponseExample(fieldMeta.modelRef);
29
+ });
30
+ const result = arraiedModel(example, arrDepth);
31
+ Reflect.defineMetadata(ref, result, ResponseExampleStorage.prototype);
32
+ return result;
33
+ };
34
+ class RequestExampleStorage {
35
+ }
36
+ const getRequestExample = (ref) => {
37
+ const existing = getPredefinedRequestExample(ref);
38
+ if (existing)
39
+ return existing;
40
+ const fieldMetas = getFieldMetas(ref);
41
+ const example = {};
42
+ const isScalar = isGqlScalar(ref);
43
+ if (isScalar)
44
+ return getScalarExample(ref);
45
+ else {
46
+ fieldMetas.forEach((fieldMeta) => {
47
+ if (!fieldMeta.isScalar && fieldMeta.isClass)
48
+ example[fieldMeta.key] = "ObjectID";
49
+ else
50
+ example[fieldMeta.key] = fieldMeta.example ?? fieldMeta.enum ? arraiedModel(fieldMeta.example ?? (fieldMeta.enum?.values)[0], fieldMeta.optArrDepth) : arraiedModel(getRequestExample(fieldMeta.modelRef), fieldMeta.arrDepth);
51
+ });
52
+ }
53
+ Reflect.defineMetadata(ref, example, RequestExampleStorage.prototype);
54
+ return example;
55
+ };
56
+ const makeRequestExample = (sigRef, key) => {
57
+ const [argMetas] = getArgMetas(sigRef, key);
58
+ return getExampleData(argMetas);
59
+ };
60
+ const getExampleData = (argMetas, signalType = "graphql") => Object.fromEntries(
61
+ argMetas.filter((argMeta) => argMeta.type !== "Upload").map((argMeta) => {
62
+ const [argRef, argArrDepth] = getNonArrayModel(argMeta.returns());
63
+ const example = argMeta.argsOption.example ?? getRequestExample(argRef);
64
+ return [
65
+ argMeta.name,
66
+ arraiedModel(
67
+ signalType === "restapi" && argRef.prototype === GqlJSON.prototype ? JSON.stringify(example, null, 2) : example,
68
+ argArrDepth
69
+ )
70
+ ];
71
+ })
72
+ );
73
+ const makeResponseExample = (sigRef, key) => {
74
+ const gqlMeta = getGqlMeta(sigRef, key);
75
+ const example = getResponseExample(gqlMeta.returns());
76
+ return example;
77
+ };
78
+ export {
79
+ getExampleData,
80
+ makeRequestExample,
81
+ makeResponseExample
82
+ };