@prsm/realtime 1.0.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.
Files changed (60) hide show
  1. package/package.json +49 -0
  2. package/src/adapters/postgres.js +139 -0
  3. package/src/adapters/sqlite.js +177 -0
  4. package/src/client/client.js +441 -0
  5. package/src/client/connection.js +178 -0
  6. package/src/client/ids.js +26 -0
  7. package/src/client/index.js +5 -0
  8. package/src/client/queue.js +44 -0
  9. package/src/client/subscriptions/channels.js +79 -0
  10. package/src/client/subscriptions/collections.js +96 -0
  11. package/src/client/subscriptions/presence.js +98 -0
  12. package/src/client/subscriptions/records.js +123 -0
  13. package/src/client/subscriptions/rooms.js +69 -0
  14. package/src/devtools/client/dist/assets/index-CGm1NqOQ.css +1 -0
  15. package/src/devtools/client/dist/assets/index-w2FI7RvC.js +168 -0
  16. package/src/devtools/client/dist/index.html +16 -0
  17. package/src/devtools/client/index.html +15 -0
  18. package/src/devtools/client/package.json +17 -0
  19. package/src/devtools/client/src/App.vue +173 -0
  20. package/src/devtools/client/src/components/ConnectionPicker.vue +38 -0
  21. package/src/devtools/client/src/components/JsonView.vue +18 -0
  22. package/src/devtools/client/src/composables/useApi.js +71 -0
  23. package/src/devtools/client/src/composables/useHighlight.js +57 -0
  24. package/src/devtools/client/src/main.js +5 -0
  25. package/src/devtools/client/src/style.css +440 -0
  26. package/src/devtools/client/src/views/ChannelsView.vue +27 -0
  27. package/src/devtools/client/src/views/CollectionsView.vue +61 -0
  28. package/src/devtools/client/src/views/MetadataView.vue +108 -0
  29. package/src/devtools/client/src/views/RecordsView.vue +30 -0
  30. package/src/devtools/client/src/views/RoomsView.vue +39 -0
  31. package/src/devtools/client/vite.config.js +17 -0
  32. package/src/devtools/demo/server.js +144 -0
  33. package/src/devtools/index.js +186 -0
  34. package/src/index.js +9 -0
  35. package/src/server/connection.js +116 -0
  36. package/src/server/context.js +22 -0
  37. package/src/server/managers/broadcast.js +94 -0
  38. package/src/server/managers/channels.js +118 -0
  39. package/src/server/managers/collections.js +127 -0
  40. package/src/server/managers/commands.js +55 -0
  41. package/src/server/managers/connections.js +111 -0
  42. package/src/server/managers/instance.js +125 -0
  43. package/src/server/managers/persistence.js +371 -0
  44. package/src/server/managers/presence.js +217 -0
  45. package/src/server/managers/pubsub.js +242 -0
  46. package/src/server/managers/record-subscriptions.js +123 -0
  47. package/src/server/managers/records.js +110 -0
  48. package/src/server/managers/redis.js +61 -0
  49. package/src/server/managers/rooms.js +129 -0
  50. package/src/server/message-stream.js +20 -0
  51. package/src/server/server.js +878 -0
  52. package/src/server/utils/constants.js +4 -0
  53. package/src/server/utils/ids.js +5 -0
  54. package/src/server/utils/pattern-conversion.js +14 -0
  55. package/src/shared/errors.js +7 -0
  56. package/src/shared/index.js +5 -0
  57. package/src/shared/logger.js +53 -0
  58. package/src/shared/merge.js +17 -0
  59. package/src/shared/message.js +17 -0
  60. package/src/shared/status.js +7 -0
@@ -0,0 +1,4 @@
1
+ export const PUB_SUB_CHANNEL_PREFIX = "mesh:pubsub:"
2
+ export const RECORD_PUB_SUB_CHANNEL = "mesh:record-updates"
3
+ export const RECORD_KEY_PREFIX = "mesh:record:"
4
+ export const RECORD_VERSION_KEY_PREFIX = "mesh:record-version:"
@@ -0,0 +1,5 @@
1
+ import { randomUUID } from "node:crypto"
2
+
3
+ export function generateConnectionId() {
4
+ return randomUUID()
5
+ }
@@ -0,0 +1,14 @@
1
+ export function convertToSqlPattern(pattern) {
2
+ return pattern
3
+ .replace(/\^/g, "")
4
+ .replace(/\$/g, "")
5
+ .replace(/\./g, "_")
6
+ .replace(/\*/g, "%")
7
+ .replace(/\+/g, "%")
8
+ .replace(/\?/g, "_")
9
+ .replace(/\\\\/g, "\\")
10
+ .replace(/\\\./g, ".")
11
+ .replace(/\\\*/g, "*")
12
+ .replace(/\\\+/g, "+")
13
+ .replace(/\\\?/g, "?")
14
+ }
@@ -0,0 +1,7 @@
1
+ export class CodeError extends Error {
2
+ constructor(message, code, name) {
3
+ super(message)
4
+ if (typeof code === "string") this.code = code
5
+ this.name = typeof name === "string" ? name : "CodeError"
6
+ }
7
+ }
@@ -0,0 +1,5 @@
1
+ export { CodeError } from "./errors.js"
2
+ export { LogLevel, Logger, clientLogger, serverLogger, logger } from "./logger.js"
3
+ export { deepMerge, isObject } from "./merge.js"
4
+ export { parseCommand, stringifyCommand } from "./message.js"
5
+ export { Status } from "./status.js"
@@ -0,0 +1,53 @@
1
+ /** @enum {number} */
2
+ export const LogLevel = {
3
+ NONE: 0,
4
+ ERROR: 1,
5
+ WARN: 2,
6
+ INFO: 3,
7
+ DEBUG: 4,
8
+ }
9
+
10
+ const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"
11
+
12
+ export class Logger {
13
+ constructor(config) {
14
+ this.config = {
15
+ level: config?.level ?? LogLevel.INFO,
16
+ prefix: config?.prefix ?? "[mesh]",
17
+ styling: config?.styling ?? isBrowser,
18
+ }
19
+ }
20
+
21
+ configure(config) {
22
+ this.config = { ...this.config, ...config }
23
+ }
24
+
25
+ info(...args) {
26
+ if (this.config.level >= LogLevel.INFO) this._log("log", ...args)
27
+ }
28
+
29
+ warn(...args) {
30
+ if (this.config.level >= LogLevel.WARN) this._log("warn", ...args)
31
+ }
32
+
33
+ error(...args) {
34
+ if (this.config.level >= LogLevel.ERROR) this._log("error", ...args)
35
+ }
36
+
37
+ debug(...args) {
38
+ if (this.config.level >= LogLevel.DEBUG) this._log("debug", ...args)
39
+ }
40
+
41
+ _log(method, ...args) {
42
+ if (this.config.styling && isBrowser) {
43
+ const style = "background: #000; color: #FFA07A; padding: 2px 4px; border-radius: 2px;"
44
+ console[method](`%c${this.config.prefix}%c`, style, "", ...args)
45
+ } else {
46
+ console[method](this.config.prefix, ...args)
47
+ }
48
+ }
49
+ }
50
+
51
+ export const clientLogger = new Logger({ level: LogLevel.ERROR, styling: true })
52
+ export const serverLogger = new Logger({ level: LogLevel.ERROR, styling: false })
53
+ export const logger = isBrowser ? clientLogger : serverLogger
@@ -0,0 +1,17 @@
1
+ export function isObject(value) {
2
+ return value !== null && typeof value === "object" && !Array.isArray(value)
3
+ }
4
+
5
+ export function deepMerge(target, source) {
6
+ if (!isObject(target) || !isObject(source)) return source
7
+
8
+ const result = { ...target }
9
+ for (const key in source) {
10
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
11
+ result[key] = isObject(source[key]) && isObject(target[key])
12
+ ? deepMerge(target[key], source[key])
13
+ : source[key]
14
+ }
15
+ }
16
+ return result
17
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @typedef {{ id?: number, command: string, payload: any }} Command
3
+ */
4
+
5
+ /** @param {string} data */
6
+ export function parseCommand(data) {
7
+ try {
8
+ return JSON.parse(data)
9
+ } catch {
10
+ return { command: "", payload: {} }
11
+ }
12
+ }
13
+
14
+ /** @param {Command} command */
15
+ export function stringifyCommand(command) {
16
+ return JSON.stringify(command)
17
+ }
@@ -0,0 +1,7 @@
1
+ /** @enum {number} */
2
+ export const Status = {
3
+ ONLINE: 3,
4
+ CONNECTING: 2,
5
+ RECONNECTING: 1,
6
+ OFFLINE: 0,
7
+ }