@dnax/core 0.14.0 → 0.14.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/app/hono.ts CHANGED
@@ -10,6 +10,7 @@ import { getCookie, setCookie } from "hono/cookie";
10
10
  import colors from "@colors/colors/safe";
11
11
  import { serveStatic, getConnInfo } from "hono/bun";
12
12
  import { consola } from "consola";
13
+
13
14
  import { cors } from "hono/cors";
14
15
  import { asyncLocalStorage, sessionStorage } from "../lib/asyncLocalStorage";
15
16
  import { localSession } from "../lib/session";
@@ -40,6 +41,7 @@ import { v4 } from "uuid";
40
41
  const cache = bentoCache.namespace("DNAX_API");
41
42
  const app = new Hono();
42
43
  const API_PATH = "/api";
44
+
43
45
  function HonoInstance(): typeof app {
44
46
  // Public assets
45
47
  app.get(
@@ -364,7 +366,7 @@ function HonoInstance(): typeof app {
364
366
  // Exec service
365
367
  if (action == "execService") {
366
368
  if (!service) return fn.error("Service not found", 404);
367
- let fx = service.exec || service.fx;
369
+ let fx = service?.exec || service?.fx;
368
370
  if (fx) {
369
371
  response = await fx({
370
372
  io: Cfg.io,
package/app/index.ts CHANGED
@@ -4,9 +4,13 @@ import { init } from "../lib";
4
4
  import { hookDatabase } from "../lib/database";
5
5
  import killPort from "kill-port";
6
6
  import boxen from "boxen";
7
+ import { loadSocket } from "../lib/socket";
8
+ import pidusage from "pidusage";
7
9
  import "@colors/colors";
8
10
  import pkg from "../package.json";
9
11
  import findPort from "find-open-port";
12
+ import { Server } from "socket.io";
13
+ import { webSocketServer } from "../lib/socket/instance";
10
14
  import { HonoInstance } from "./hono";
11
15
  type configRunApp = {
12
16
  register?: Array<Function>;
@@ -39,6 +43,7 @@ async function runApp(config?: configRunApp, clb?: Function) {
39
43
  // Load all ressouce
40
44
  await init();
41
45
  const HonoApp = HonoInstance();
46
+ //await loadSocket(HonoApp);
42
47
  //BeforeStart
43
48
  if (config?.beforeStart) {
44
49
  for (const fn of config?.beforeStart) {
@@ -46,10 +51,18 @@ async function runApp(config?: configRunApp, clb?: Function) {
46
51
  }
47
52
  }
48
53
 
49
- Bun.serve({
54
+ var server = Bun.serve({
50
55
  port: PORT,
51
- fetch: HonoApp.fetch,
56
+ fetch: (req, server) => {
57
+ if (server.upgrade(req)) {
58
+ // handle authentication
59
+ return;
60
+ }
61
+
62
+ return HonoApp.fetch(req, server);
63
+ },
52
64
  maxRequestBodySize: 1024 * 1024 * 900,
65
+ websocket: webSocketServer(server),
53
66
  });
54
67
 
55
68
  console.log();
package/define/index.ts CHANGED
@@ -22,7 +22,7 @@ function Config(config: Config) {
22
22
 
23
23
  function Collection(col: Collection) {
24
24
  col.timestamps = col?.timestamps ?? true;
25
-
25
+ if (!col?.fields) col.fields = [];
26
26
  return col;
27
27
  }
28
28
 
@@ -71,6 +71,11 @@ class useRest {
71
71
  #tenant_id: string;
72
72
  #session: ClientSession | null | undefined;
73
73
  #useCustomApi: boolean = true;
74
+ /**
75
+ Direct Api Mongo , use it with caution
76
+ */
77
+ db: Tenant["database"]["db"];
78
+
74
79
  constructor(options: options) {
75
80
  this.#c = options.c;
76
81
  this.#useCustomApi = options.useCustomApi ?? true;
@@ -78,6 +83,8 @@ class useRest {
78
83
  this.#session = null;
79
84
  this.#tenant = getTenant(this.#tenant_id);
80
85
  this.#useHook = options?.useHook ?? true;
86
+ this.db = this.#tenant.database.db;
87
+
81
88
  /* if (options?.useHook == undefined || options?.useHook == null) {
82
89
  this.#useHook = true;
83
90
  } else {
package/lib/index.ts CHANGED
@@ -4,10 +4,11 @@ import { loadEndpoints } from "./endpoint";
4
4
  import { loadServices } from "./service";
5
5
  import { initCron } from "./cron";
6
6
  import { loadPermissions } from "./permissions";
7
- import { loadSocket } from "./socket";
7
+ import { loadSocket } from "../lib/socket";
8
8
  import { loadAutoRoutes } from "./routes";
9
9
  // load all ressource
10
10
  async function init(cf = { app: null }) {
11
+ await loadSocket();
11
12
  // load all tenants database
12
13
  await connectTenantsDatabase();
13
14
  // load all collections
@@ -22,9 +23,6 @@ async function init(cf = { app: null }) {
22
23
  // load Service
23
24
  loadServices();
24
25
 
25
- // load Socket
26
- await loadSocket();
27
-
28
26
  // load all loadEndpoints
29
27
  await loadEndpoints();
30
28
 
package/lib/service.ts CHANGED
@@ -36,7 +36,7 @@ async function loadServices() {
36
36
 
37
37
  function getService(name: string, tenant_id: string): Service | undefined {
38
38
  return Cfg.services?.find(
39
- (s) => s?.tenant_id == tenant_id && s?.name == name && s?.fx
39
+ (s) => s?.tenant_id == tenant_id && s?.name == name && (s?.fx || s?.exec)
40
40
  );
41
41
  }
42
42
 
@@ -1,16 +1,11 @@
1
- import { Cfg } from "../config";
1
+ import { Cfg } from "../../config";
2
2
  import { Server } from "socket.io";
3
3
  import consola from "consola";
4
4
  import { Glob } from "bun";
5
5
  import path from "path";
6
- import { useRest } from "../driver/mongo";
6
+ import { useRest } from "../../driver/mongo";
7
+ import { io } from "./instance";
7
8
  async function loadSocket() {
8
- var io = new Server(Number(Cfg.server?.socket?.port || 9000), {
9
- cors: {
10
- ...Cfg.server.cors,
11
- credentials: true,
12
- },
13
- });
14
9
  /* io.on("connection", (socket) => {
15
10
  console.log("ok");
16
11
  }); */
@@ -22,18 +17,20 @@ async function loadSocket() {
22
17
  cwd: Cfg.cwd,
23
18
  })) {
24
19
  let fullPathFile = path.join(Cfg.cwd || "", file);
20
+
25
21
  await import(fullPathFile)
26
22
  .then((inject) => {
27
23
  let socketInstance = inject?.default || null;
24
+
28
25
  if (
29
26
  socketInstance &&
30
27
  socketInstance?.enabled &&
31
- socketInstance?.handler
28
+ socketInstance?.exec
32
29
  ) {
33
30
  let rest = new useRest({
34
31
  tenant_id: t.id,
35
32
  });
36
- socketInstance.handler({
33
+ socketInstance.exec({
37
34
  io,
38
35
  rest,
39
36
  });
@@ -0,0 +1,113 @@
1
+ import type { ServerWebSocket, WebSocketHandler, Server } from "bun";
2
+ import { EventEmitter } from "events";
3
+ import { v4 } from "uuid";
4
+ const wsClients = new Map<string, ServerWebSocket>();
5
+ const wsEvents: optionsIo[] = [];
6
+
7
+ class Io {
8
+ constructor() {}
9
+ on(event: string, cb: Function) {
10
+ wsEvents.push({
11
+ type: "on",
12
+ event: event,
13
+ cb: cb,
14
+ });
15
+ }
16
+ emit(event: string, data: any) {
17
+ wsEvents.push({
18
+ type: "emit",
19
+ event: event,
20
+ data: data,
21
+ });
22
+ }
23
+ }
24
+
25
+ const io = new Io();
26
+ type optionsIo = {
27
+ type: "on" | "emit";
28
+ event: string | "connection" | "close";
29
+ data?: any;
30
+ cb?: Function;
31
+ token?: string;
32
+ uuid?: string;
33
+ };
34
+
35
+ export type socketIoType = {
36
+ id: string;
37
+ on: <T extends "connection" | "close" | string>(
38
+ event: T,
39
+ cb: (socket: {
40
+ id: string;
41
+ emit: (event: string, data: any) => void;
42
+ }) => void
43
+ ) => void;
44
+ emit: (event: string, data: any) => void;
45
+ broadcast: (event: string, data: any) => void;
46
+ };
47
+
48
+ function webSocketServer(server: Server): WebSocketHandler {
49
+ return {
50
+ open: (ws) => {
51
+ let id = v4();
52
+ ws.id = id;
53
+ wsClients.set(id, ws);
54
+ // set Id to client and emit it
55
+ ws.send(JSON.stringify({ type: "setId", id: id }));
56
+
57
+ // run all listenners event for connection
58
+ let evs = wsEvents.filter(
59
+ (e) => e.type == "on" && e?.event == "connection"
60
+ );
61
+
62
+ // exec cb for conenction
63
+ evs?.map((ev) => {
64
+ if (ev && ev.cb) {
65
+ ev.cb({
66
+ id: id,
67
+ emit: (event: string, data: any) =>
68
+ ws.send(JSON.stringify({ type: "emit", event, data })),
69
+ });
70
+ }
71
+ });
72
+ },
73
+ close(ws, code, reason) {
74
+ console.log("close", code, reason);
75
+ console.log(ws.id);
76
+ },
77
+ message: (ws, message: any) => {
78
+ try {
79
+ let options: optionsIo = JSON.parse(message);
80
+
81
+ // find all listeners : On
82
+ let evs = wsEvents.filter(
83
+ (e) => e.event == options?.event && e?.type == "on"
84
+ );
85
+
86
+ // run all listeners function if matchs
87
+ evs?.map((ev) => {
88
+ if (ev && ev.cb) {
89
+ ev.cb({
90
+ data: options.data,
91
+ ws: {
92
+ broadcast: (event: string, data: any) => {
93
+ // send to all clients
94
+ wsClients.forEach((client) => {
95
+ client.send(JSON.stringify({ type: "emit", event, data }));
96
+ });
97
+ },
98
+ emit: (event: string, data: any) =>
99
+ ws.send(JSON.stringify({ type: "emit", event, data })),
100
+ },
101
+ });
102
+ }
103
+ });
104
+
105
+ //wsEvents.on(options.event)
106
+ } catch (err) {
107
+ //console.log("Not a valid JSON string", err?.message);
108
+ }
109
+ },
110
+ };
111
+ }
112
+
113
+ export { webSocketServer, wsClients, io };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dnax/core",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "@types/fs-extra": "^11.0.4",
12
12
  "@types/mime-types": "^2.1.4",
13
13
  "@types/nodemailer": "^6.4.15",
14
+ "@types/pidusage": "^2.0.5",
14
15
  "@types/uuid": "^10.0.0"
15
16
  },
16
17
  "peerDependencies": {
@@ -37,7 +38,7 @@
37
38
  "find-open-port": "^2.0.3",
38
39
  "fs-extra": "^11.2.0",
39
40
  "generate-unique-id": "^2.0.3",
40
- "groq-sdk": "^0.7.0",
41
+ "groq-sdk": "^0.8.0",
41
42
  "hono": "^4.6.3",
42
43
  "joi": "^17.13.3",
43
44
  "json-joy": "^16.8.0",
@@ -45,14 +46,15 @@
45
46
  "mime-types": "^2.1.35",
46
47
  "mingo": "^6.4.15",
47
48
  "moment": "^2.30.1",
48
- "mongodb": "^6.8.0",
49
+ "mongodb": "^6.10.0",
49
50
  "nodemailer": "^6.9.14",
50
51
  "ollama": "^0.5.9",
51
- "openai": "^4.71.1",
52
+ "openai": "^4.72.0",
53
+ "pidusage": "^3.0.2",
52
54
  "radash": "^12.1.0",
53
55
  "sharp": "^0.33.5",
54
56
  "signaldb": "^0.18.0",
55
- "socket.io": "^4.7.5",
57
+ "socket.io": "^4.8.1",
56
58
  "ufo": "^1.5.3",
57
59
  "urlencode": "^2.0.0",
58
60
  "uuid": "^10.0.0"
package/types/index.ts CHANGED
@@ -6,9 +6,9 @@ import type { Db, MongoClient } from "mongodb";
6
6
  import { useRest } from "../driver/mongo/rest";
7
7
  import { sessionStorage } from "../lib/asyncLocalStorage";
8
8
  import type { Context, Hono } from "hono";
9
- import type { Server as ServerIO, Socket as SocketType } from "socket.io";
9
+ //import type { Server as ServerIO, Socket as SocketType } from "socket.io";
10
10
 
11
- type Io = InstanceType<typeof ServerIO>;
11
+ import type { socketIoType } from "../lib/socket/instance";
12
12
 
13
13
  import { fn } from "../utils";
14
14
  import type {
@@ -20,7 +20,7 @@ import type { RouterRoute } from "hono/types";
20
20
  import type { MongoClientOptions } from "mongodb";
21
21
  export type Socket = {
22
22
  enabled: boolean;
23
- handler: (ctx: { rest: useRest; io: Io; session: sessionCtx }) => void;
23
+ exec: (ctx: { rest: useRest; io: socketIoType }) => void;
24
24
  };
25
25
 
26
26
  export type Tenant = {
package/utils/index.ts CHANGED
@@ -12,11 +12,16 @@ import collect from "collect.js";
12
12
  import * as uuid from "uuid";
13
13
  import * as urlencode from "urlencode";
14
14
  import dotJson from "dot-object";
15
+ import deepClone from "deep-clone";
15
16
 
16
17
  const JWT_SECRET = process?.env?.JWT_SECRET || "secret-libv";
17
18
  import * as _ from "radash";
18
19
  import { email } from "../lib/mail";
19
20
 
21
+ function copy(data: object): object | any {
22
+ return deepClone(data);
23
+ }
24
+
20
25
  const jwt = {
21
26
  verify: (token: string): { decode: any; valid: boolean; error: any } => {
22
27
  let decode = null;
@@ -343,4 +348,5 @@ export {
343
348
  Otp, // Otp utils
344
349
  urlencode,
345
350
  stringToBoolean,
351
+ copy,
346
352
  };