@kokimoki/app 0.6.8 → 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 (48) hide show
  1. package/dist/index.d.ts +5 -1
  2. package/dist/index.js +5 -1
  3. package/dist/kokimoki-client copy.d.ts +57 -0
  4. package/dist/kokimoki-client copy.js +259 -0
  5. package/dist/kokimoki-client-refactored.d.ts +67 -0
  6. package/dist/kokimoki-client-refactored.js +422 -0
  7. package/dist/kokimoki-client.d.ts +26 -14
  8. package/dist/kokimoki-client.js +292 -103
  9. package/dist/kokimoki-queue.d.ts +34 -0
  10. package/dist/kokimoki-queue.js +30 -0
  11. package/dist/kokimoki-schema.d.ts +52 -0
  12. package/dist/kokimoki-schema.js +92 -0
  13. package/dist/kokimoki-store.d.ts +13 -0
  14. package/dist/kokimoki-store.js +48 -0
  15. package/dist/kokimoki-transaction.d.ts +25 -0
  16. package/dist/kokimoki-transaction.js +99 -0
  17. package/dist/message-queue.d.ts +8 -0
  18. package/dist/message-queue.js +19 -0
  19. package/dist/room-subscription-mode.d.ts +5 -0
  20. package/dist/room-subscription-mode.js +6 -0
  21. package/dist/room-subscription.d.ts +15 -0
  22. package/dist/room-subscription.js +49 -0
  23. package/dist/synced-schema.d.ts +52 -0
  24. package/dist/synced-schema.js +92 -0
  25. package/dist/synced-store copy.d.ts +7 -0
  26. package/dist/synced-store copy.js +9 -0
  27. package/dist/synced-types.d.ts +45 -0
  28. package/dist/synced-types.js +72 -0
  29. package/dist/types/events.d.ts +1 -2
  30. package/dist/version.d.ts +1 -1
  31. package/dist/version.js +1 -1
  32. package/dist/ws-message/index.d.ts +3 -0
  33. package/dist/ws-message/index.js +3 -0
  34. package/dist/ws-message/ws-message-reader.d.ts +9 -0
  35. package/dist/ws-message/ws-message-reader.js +17 -0
  36. package/dist/ws-message/ws-message-type.d.ts +4 -0
  37. package/dist/ws-message/ws-message-type.js +5 -0
  38. package/dist/ws-message/ws-message-writer.d.ts +12 -0
  39. package/dist/ws-message/ws-message-writer.js +30 -0
  40. package/dist/ws-message-reader.d.ts +11 -0
  41. package/dist/ws-message-reader.js +36 -0
  42. package/dist/ws-message-type.d.ts +9 -0
  43. package/dist/ws-message-type.js +10 -0
  44. package/dist/ws-message-writer.d.ts +9 -0
  45. package/dist/ws-message-writer.js +45 -0
  46. package/dist/ws-message.d.ts +14 -0
  47. package/dist/ws-message.js +34 -0
  48. package/package.json +4 -4
@@ -0,0 +1,48 @@
1
+ import * as Y from "yjs";
2
+ import { proxy as yjsProxy } from "valtio";
3
+ import { bind as yjsBind } from "valtio-yjs";
4
+ import DeepProxy from "proxy-deep";
5
+ import { RoomSubscriptionMode } from "./room-subscription-mode";
6
+ export class KokimokiStore {
7
+ roomName;
8
+ mode;
9
+ doc;
10
+ proxy;
11
+ root;
12
+ defaultValue;
13
+ docRoot;
14
+ constructor(roomName, schema, mode = RoomSubscriptionMode.ReadWrite) {
15
+ this.roomName = roomName;
16
+ this.mode = mode;
17
+ // Construct Y doc
18
+ this.doc = new Y.Doc();
19
+ // Construct proxy object
20
+ this.docRoot = this.doc.getMap("root");
21
+ this.proxy = yjsProxy();
22
+ // @ts-ignore
23
+ yjsBind(this.proxy, this.docRoot);
24
+ // Create root proxy
25
+ const store = this;
26
+ // @ts-ignore
27
+ this.root = new DeepProxy(this.proxy, {
28
+ get() {
29
+ return this.nest(function () { });
30
+ },
31
+ apply() {
32
+ let obj = store.proxy;
33
+ for (let i = 0; i < this.path.length - 1; i++) {
34
+ obj = obj[this.path[i]];
35
+ }
36
+ return {
37
+ roomName: store.roomName,
38
+ doc: store.doc,
39
+ path: this.path,
40
+ obj,
41
+ key: this.path[this.path.length - 1],
42
+ };
43
+ },
44
+ });
45
+ // Set default value
46
+ this.defaultValue = schema.defaultValue;
47
+ }
48
+ }
@@ -0,0 +1,25 @@
1
+ import type { KokimokiQueue } from "./kokimoki-queue";
2
+ import type { KokimokiSchema as S } from "./kokimoki-schema";
3
+ import type { KokimokiClient } from "./kokimoki-client";
4
+ export declare class KokimokiTransaction {
5
+ private kmClient;
6
+ private _clones;
7
+ private _updates;
8
+ private _consumeMessagesInRooms;
9
+ constructor(kmClient: KokimokiClient<any>);
10
+ private _parseTarget;
11
+ private _parsePath;
12
+ private _getClone;
13
+ set<T>(target: T, value: T): void;
14
+ delete<T>(target: T): void;
15
+ push<T>(target: T[], value: T): void;
16
+ queueMessage<T>(queue: KokimokiQueue<S.Generic<T>>, payload: T): void;
17
+ consumeMessage<T>(queue: KokimokiQueue<S.Generic<T>>, messageId: string): void;
18
+ getUpdates(): Promise<{
19
+ updates: {
20
+ roomName: string;
21
+ update: Uint8Array;
22
+ }[];
23
+ consumedMessages: Set<string>;
24
+ }>;
25
+ }
@@ -0,0 +1,99 @@
1
+ import * as Y from "yjs";
2
+ import { proxy as yjsProxy } from "valtio";
3
+ import { bind as yjsBind } from "valtio-yjs";
4
+ export class KokimokiTransaction {
5
+ kmClient;
6
+ _clones = new Map();
7
+ _updates = new Map();
8
+ _consumeMessagesInRooms = new Set();
9
+ constructor(kmClient) {
10
+ this.kmClient = kmClient;
11
+ }
12
+ _parseTarget(target) {
13
+ return target();
14
+ }
15
+ _parsePath(obj, path) {
16
+ for (let i = 0; i < path.length - 1; i++) {
17
+ if (!(path[i] in obj)) {
18
+ obj[path[i]] = {};
19
+ }
20
+ obj = obj[path[i]];
21
+ }
22
+ return { obj, key: path[path.length - 1] };
23
+ }
24
+ _getClone(roomName, doc) {
25
+ if (!this._clones.has(roomName)) {
26
+ // Clone doc
27
+ const docClone = new Y.Doc();
28
+ const docRoot = docClone.getMap("root");
29
+ Y.applyUpdate(docClone, Y.encodeStateAsUpdate(doc));
30
+ // Set up proxy
31
+ const proxyClone = yjsProxy();
32
+ const unbindProxy = yjsBind(proxyClone, docRoot);
33
+ // Listen for updates
34
+ docClone.on("update", (update) => {
35
+ if (this._updates.has(roomName)) {
36
+ const prevUpdate = this._updates.get(roomName);
37
+ const nextUpdate = Y.mergeUpdates([prevUpdate, update]);
38
+ this._updates.set(roomName, nextUpdate);
39
+ }
40
+ else {
41
+ this._updates.set(roomName, update);
42
+ }
43
+ });
44
+ this._clones.set(roomName, { docClone, proxyClone, unbindProxy });
45
+ }
46
+ return this._clones.get(roomName);
47
+ }
48
+ set(target, value) {
49
+ const { roomName, doc, path } = this._parseTarget(target);
50
+ const { proxyClone } = this._getClone(roomName, doc);
51
+ const { obj, key } = this._parsePath(proxyClone, path);
52
+ obj[key] = value;
53
+ }
54
+ delete(target) {
55
+ const { roomName, doc, path } = this._parseTarget(target);
56
+ const { proxyClone } = this._getClone(roomName, doc);
57
+ const { obj, key } = this._parsePath(proxyClone, path);
58
+ delete obj[key];
59
+ }
60
+ push(target, value) {
61
+ const { roomName, doc, path } = this._parseTarget(target);
62
+ const { proxyClone } = this._getClone(roomName, doc);
63
+ const { obj, key } = this._parsePath(proxyClone, path);
64
+ if (!(key in obj)) {
65
+ obj[key] = [];
66
+ }
67
+ obj[key].push(value);
68
+ }
69
+ queueMessage(queue, payload) {
70
+ const messageId = Math.random().toString(36);
71
+ this.set(queue.root[messageId], {
72
+ timestamp: this.kmClient.serverTimestamp(),
73
+ payload,
74
+ });
75
+ }
76
+ consumeMessage(queue, messageId) {
77
+ if (!queue.proxy[messageId]) {
78
+ throw new Error(`Message ${messageId} does not exist or has already been consumed`);
79
+ }
80
+ this.delete(queue.root[messageId]);
81
+ this._consumeMessagesInRooms.add(queue.roomName);
82
+ }
83
+ async getUpdates() {
84
+ // Wait for doc update handling to finish
85
+ return await new Promise((resolve) => setTimeout(() => {
86
+ // Clean up
87
+ for (const { unbindProxy } of this._clones.values()) {
88
+ unbindProxy();
89
+ }
90
+ // Generates updates
91
+ const updates = Array.from(this._updates.entries()).map(([roomName, update]) => ({
92
+ roomName,
93
+ update,
94
+ }));
95
+ // Done
96
+ resolve({ updates, consumedMessages: this._consumeMessagesInRooms });
97
+ }));
98
+ }
99
+ }
@@ -0,0 +1,8 @@
1
+ import { SyncedStore } from "./synced-store";
2
+ export declare class MessageQueue<T> extends SyncedStore<{
3
+ messages: T[];
4
+ }> {
5
+ name: string;
6
+ constructor(name: string);
7
+ push(message: T): Promise<Uint8Array>;
8
+ }
@@ -0,0 +1,19 @@
1
+ import EventEmitter from "events";
2
+ import { SyncedStore } from "./synced-store";
3
+ import Y from "yjs";
4
+ export class MessageQueue extends SyncedStore {
5
+ name;
6
+ constructor(name) {
7
+ super({ messages: [] });
8
+ this.name = name;
9
+ }
10
+ async push(message) {
11
+ // Construct Y update to push the message to the queue
12
+ const id = crypto.randomUUID();
13
+ const ydoc = new Y.Doc();
14
+ const map = ydoc.getMap("messages");
15
+ map.set(id, message);
16
+ const update = Y.encodeStateAsUpdate(ydoc);
17
+ return update;
18
+ }
19
+ }
@@ -0,0 +1,5 @@
1
+ export declare enum RoomSubscriptionMode {
2
+ Read = "r",
3
+ Write = "w",
4
+ ReadWrite = "b"
5
+ }
@@ -0,0 +1,6 @@
1
+ export var RoomSubscriptionMode;
2
+ (function (RoomSubscriptionMode) {
3
+ RoomSubscriptionMode["Read"] = "r";
4
+ RoomSubscriptionMode["Write"] = "w";
5
+ RoomSubscriptionMode["ReadWrite"] = "b";
6
+ })(RoomSubscriptionMode || (RoomSubscriptionMode = {}));
@@ -0,0 +1,15 @@
1
+ import type { KokimokiStore } from "./kokimoki-store";
2
+ import type { KokimokiClient } from "./kokimoki-client";
3
+ export declare class RoomSubscription {
4
+ private kmClient;
5
+ readonly store: KokimokiStore<any>;
6
+ private _joined;
7
+ private _roomHash?;
8
+ private _onDisconnect;
9
+ constructor(kmClient: KokimokiClient, store: KokimokiStore<any>);
10
+ get roomName(): string;
11
+ get roomHash(): number;
12
+ get joined(): boolean;
13
+ applyInitialResponse(roomHash: number, initialUpdate?: Uint8Array): Promise<void>;
14
+ close(): void;
15
+ }
@@ -0,0 +1,49 @@
1
+ import * as Y from "yjs";
2
+ import { RoomSubscriptionMode } from "./room-subscription-mode";
3
+ export class RoomSubscription {
4
+ kmClient;
5
+ store;
6
+ _joined = false;
7
+ _roomHash;
8
+ _onDisconnect = () => {
9
+ this._joined = false;
10
+ };
11
+ constructor(kmClient, store) {
12
+ this.kmClient = kmClient;
13
+ this.store = store;
14
+ kmClient.on("disconnected", this._onDisconnect);
15
+ }
16
+ get roomName() {
17
+ return this.store.roomName;
18
+ }
19
+ get roomHash() {
20
+ if (!this._roomHash) {
21
+ throw new Error("Room not joined");
22
+ }
23
+ return this._roomHash;
24
+ }
25
+ get joined() {
26
+ return this._joined;
27
+ }
28
+ async applyInitialResponse(roomHash, initialUpdate) {
29
+ this._roomHash = roomHash;
30
+ // Apply initial state
31
+ if (initialUpdate) {
32
+ Y.applyUpdate(this.store.doc, initialUpdate, this);
33
+ }
34
+ // Set defaults if doc is empty after sync (only possible in ReadWrite mode)
35
+ if (this.store.mode === RoomSubscriptionMode.ReadWrite) {
36
+ await this.kmClient.transact((t) => {
37
+ for (const key in this.store.defaultValue) {
38
+ if (!this.store.proxy.hasOwnProperty(key)) {
39
+ t.set(this.store.root[key], this.store.defaultValue[key]);
40
+ }
41
+ }
42
+ });
43
+ }
44
+ this._joined = true;
45
+ }
46
+ close() {
47
+ this.kmClient.off("disconnected", this._onDisconnect);
48
+ }
49
+ }
@@ -0,0 +1,52 @@
1
+ export declare namespace S {
2
+ abstract class Generic<T> {
3
+ abstract get defaultValue(): T;
4
+ abstract set defaultValue(value: T);
5
+ }
6
+ class Number extends Generic<number> {
7
+ defaultValue: number;
8
+ constructor(defaultValue?: number);
9
+ }
10
+ function number(defaultValue?: number): Number;
11
+ class String extends Generic<string> {
12
+ defaultValue: string;
13
+ constructor(defaultValue?: string);
14
+ }
15
+ function string(defaultValue?: string): String;
16
+ class Boolean extends Generic<boolean> {
17
+ defaultValue: boolean;
18
+ constructor(defaultValue?: boolean);
19
+ }
20
+ function boolean(defaultValue?: boolean): Boolean;
21
+ class Struct<Data extends Record<string, Generic<unknown>>> extends Generic<{
22
+ [key in keyof Data]: Data[key]["defaultValue"];
23
+ }> {
24
+ fields: Data;
25
+ constructor(fields: Data);
26
+ get defaultValue(): {
27
+ [key in keyof Data]: Data[key]["defaultValue"];
28
+ };
29
+ set defaultValue(value: {
30
+ [key in keyof Data]: Data[key]["defaultValue"];
31
+ });
32
+ }
33
+ function struct<Data extends Record<string, Generic<unknown>>>(schema: Data): Struct<Data>;
34
+ class Dict<T extends Generic<unknown>> {
35
+ schema: T;
36
+ defaultValue: {
37
+ [key: string]: T["defaultValue"];
38
+ };
39
+ constructor(schema: T, defaultValue?: {
40
+ [key: string]: T["defaultValue"];
41
+ });
42
+ }
43
+ function dict<T extends Generic<unknown>>(schema: T, defaultValue?: {
44
+ [key: string]: T["defaultValue"];
45
+ }): Dict<T>;
46
+ class List<T extends Generic<unknown>> extends Generic<T["defaultValue"][]> {
47
+ schema: T;
48
+ defaultValue: T["defaultValue"][];
49
+ constructor(schema: T, defaultValue?: T["defaultValue"][]);
50
+ }
51
+ function list<T extends Generic<unknown>>(schema: T, defaultValue?: T["defaultValue"][]): List<T>;
52
+ }
@@ -0,0 +1,92 @@
1
+ export var S;
2
+ (function (S) {
3
+ class Generic {
4
+ }
5
+ S.Generic = Generic;
6
+ class Number extends Generic {
7
+ defaultValue;
8
+ constructor(defaultValue = 0) {
9
+ super();
10
+ this.defaultValue = defaultValue;
11
+ }
12
+ }
13
+ S.Number = Number;
14
+ function number(defaultValue = 0) {
15
+ return new Number(defaultValue);
16
+ }
17
+ S.number = number;
18
+ class String extends Generic {
19
+ defaultValue;
20
+ constructor(defaultValue = "") {
21
+ super();
22
+ this.defaultValue = defaultValue;
23
+ }
24
+ }
25
+ S.String = String;
26
+ function string(defaultValue = "") {
27
+ return new String(defaultValue);
28
+ }
29
+ S.string = string;
30
+ class Boolean extends Generic {
31
+ defaultValue;
32
+ constructor(defaultValue = false) {
33
+ super();
34
+ this.defaultValue = defaultValue;
35
+ }
36
+ }
37
+ S.Boolean = Boolean;
38
+ function boolean(defaultValue = false) {
39
+ return new Boolean(defaultValue);
40
+ }
41
+ S.boolean = boolean;
42
+ class Struct extends Generic {
43
+ fields;
44
+ constructor(fields) {
45
+ super();
46
+ this.fields = fields;
47
+ }
48
+ get defaultValue() {
49
+ return Object.entries(this.fields).reduce((acc, [key, field]) => {
50
+ acc[key] = field.defaultValue;
51
+ return acc;
52
+ }, {});
53
+ }
54
+ set defaultValue(value) {
55
+ for (const [key, field] of Object.entries(this.fields)) {
56
+ field.defaultValue = value[key];
57
+ }
58
+ }
59
+ }
60
+ S.Struct = Struct;
61
+ function struct(schema) {
62
+ return new Struct(schema);
63
+ }
64
+ S.struct = struct;
65
+ class Dict {
66
+ schema;
67
+ defaultValue;
68
+ constructor(schema, defaultValue = {}) {
69
+ this.schema = schema;
70
+ this.defaultValue = defaultValue;
71
+ }
72
+ }
73
+ S.Dict = Dict;
74
+ function dict(schema, defaultValue = {}) {
75
+ return new Dict(schema, defaultValue);
76
+ }
77
+ S.dict = dict;
78
+ class List extends Generic {
79
+ schema;
80
+ defaultValue;
81
+ constructor(schema, defaultValue = []) {
82
+ super();
83
+ this.schema = schema;
84
+ this.defaultValue = defaultValue;
85
+ }
86
+ }
87
+ S.List = List;
88
+ function list(schema, defaultValue = []) {
89
+ return new List(schema, defaultValue);
90
+ }
91
+ S.list = list;
92
+ })(S || (S = {}));
@@ -0,0 +1,7 @@
1
+ import type * as Y from "yjs";
2
+ import type { DocTypeDescription, MappedTypeDescription } from "@syncedstore/core/types/doc";
3
+ export declare class SyncedStore<T extends DocTypeDescription> {
4
+ readonly data: MappedTypeDescription<T>;
5
+ readonly doc: Y.Doc;
6
+ constructor(initialState: T);
7
+ }
@@ -0,0 +1,9 @@
1
+ import { syncedStore, getYjsDoc } from "@syncedstore/core";
2
+ export class SyncedStore {
3
+ data;
4
+ doc;
5
+ constructor(initialState) {
6
+ this.data = syncedStore(initialState);
7
+ this.doc = getYjsDoc(this.data);
8
+ }
9
+ }
@@ -0,0 +1,45 @@
1
+ export declare abstract class SyncedGeneric<T> {
2
+ abstract get defaultValue(): T;
3
+ abstract set defaultValue(value: T);
4
+ }
5
+ export declare class SyncedNumber extends SyncedGeneric<number> {
6
+ defaultValue: number;
7
+ constructor(defaultValue?: number);
8
+ }
9
+ export declare function syncedNumber(defaultValue?: number): SyncedNumber;
10
+ export declare class SyncedString extends SyncedGeneric<string> {
11
+ defaultValue: string;
12
+ constructor(defaultValue?: string);
13
+ }
14
+ export declare function syncedString(defaultValue?: string): SyncedString;
15
+ export declare class SyncedBoolean extends SyncedGeneric<boolean> {
16
+ defaultValue: boolean;
17
+ constructor(defaultValue?: boolean);
18
+ }
19
+ export declare function syncedBoolean(defaultValue?: boolean): SyncedBoolean;
20
+ export declare class SyncedMap<Data extends Record<string, SyncedGeneric<unknown>>> extends SyncedGeneric<{
21
+ [key in keyof Data]: Data[key]["defaultValue"];
22
+ }> {
23
+ fields: Data;
24
+ constructor(fields: Data);
25
+ get defaultValue(): {
26
+ [key in keyof Data]: Data[key]["defaultValue"];
27
+ };
28
+ set defaultValue(value: {
29
+ [key in keyof Data]: Data[key]["defaultValue"];
30
+ });
31
+ }
32
+ export declare function syncedMap<T extends Record<string, SyncedGeneric<unknown>>>(schema: T): SyncedMap<T>;
33
+ export declare class SyncedArray<T extends SyncedGeneric<unknown>> extends SyncedGeneric<T["defaultValue"][]> {
34
+ schema: T;
35
+ defaultValue: T["defaultValue"][];
36
+ constructor(schema: T, defaultValue?: T["defaultValue"][]);
37
+ }
38
+ export declare function syncedArray<T extends SyncedGeneric<unknown>>(schema: T, defaultValue?: T["defaultValue"][]): SyncedArray<T>;
39
+ export declare const S: {
40
+ number: typeof syncedNumber;
41
+ string: typeof syncedString;
42
+ boolean: typeof syncedBoolean;
43
+ map: typeof syncedMap;
44
+ array: typeof syncedArray;
45
+ };
@@ -0,0 +1,72 @@
1
+ export class SyncedGeneric {
2
+ }
3
+ export class SyncedNumber extends SyncedGeneric {
4
+ defaultValue;
5
+ constructor(defaultValue = 0) {
6
+ super();
7
+ this.defaultValue = defaultValue;
8
+ }
9
+ }
10
+ export function syncedNumber(defaultValue = 0) {
11
+ return new SyncedNumber(defaultValue);
12
+ }
13
+ export class SyncedString extends SyncedGeneric {
14
+ defaultValue;
15
+ constructor(defaultValue = "") {
16
+ super();
17
+ this.defaultValue = defaultValue;
18
+ }
19
+ }
20
+ export function syncedString(defaultValue = "") {
21
+ return new SyncedString(defaultValue);
22
+ }
23
+ export class SyncedBoolean extends SyncedGeneric {
24
+ defaultValue;
25
+ constructor(defaultValue = false) {
26
+ super();
27
+ this.defaultValue = defaultValue;
28
+ }
29
+ }
30
+ export function syncedBoolean(defaultValue = false) {
31
+ return new SyncedBoolean(defaultValue);
32
+ }
33
+ export class SyncedMap extends SyncedGeneric {
34
+ fields;
35
+ constructor(fields) {
36
+ super();
37
+ this.fields = fields;
38
+ }
39
+ get defaultValue() {
40
+ return Object.entries(this.fields).reduce((acc, [key, field]) => {
41
+ acc[key] = field.defaultValue;
42
+ return acc;
43
+ }, {});
44
+ }
45
+ set defaultValue(value) {
46
+ for (const [key, field] of Object.entries(this.fields)) {
47
+ field.defaultValue = value[key];
48
+ }
49
+ }
50
+ }
51
+ export function syncedMap(schema) {
52
+ return new SyncedMap(schema);
53
+ }
54
+ export class SyncedArray extends SyncedGeneric {
55
+ schema;
56
+ defaultValue;
57
+ constructor(schema, defaultValue = []) {
58
+ super();
59
+ this.schema = schema;
60
+ this.defaultValue = defaultValue;
61
+ }
62
+ }
63
+ export function syncedArray(schema, defaultValue = []) {
64
+ return new SyncedArray(schema, defaultValue);
65
+ }
66
+ export const S = {
67
+ number: syncedNumber,
68
+ string: syncedString,
69
+ boolean: syncedBoolean,
70
+ map: syncedMap,
71
+ array: syncedArray,
72
+ };
@@ -1,5 +1,4 @@
1
- export type KokimokiClientEvents<T> = {
2
- stateless: (room: string, from: string, data: T) => void;
1
+ export type KokimokiClientEvents = {
3
2
  connected: () => void;
4
3
  disconnected: () => void;
5
4
  };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const KOKIMOKI_APP_VERSION = "0.6.8";
1
+ export declare const KOKIMOKI_APP_VERSION = "1.0.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const KOKIMOKI_APP_VERSION = "0.6.8";
1
+ export const KOKIMOKI_APP_VERSION = "1.0.0";
@@ -0,0 +1,3 @@
1
+ export * from "../ws-message-type";
2
+ export * from "../ws-message-reader";
3
+ export * from "../ws-message-writer";
@@ -0,0 +1,3 @@
1
+ export * from "../ws-message-type";
2
+ export * from "../ws-message-reader";
3
+ export * from "../ws-message-writer";
@@ -0,0 +1,9 @@
1
+ import type { WsMessageType } from "./ws-message-type";
2
+ export declare class WsMessageReader {
3
+ private buffer;
4
+ readonly type: WsMessageType;
5
+ private _view;
6
+ private _offset;
7
+ constructor(buffer: ArrayBuffer);
8
+ readInt32(): number;
9
+ }
@@ -0,0 +1,17 @@
1
+ export class WsMessageReader {
2
+ buffer;
3
+ type;
4
+ _view;
5
+ _offset = 0;
6
+ constructor(buffer) {
7
+ this.buffer = buffer;
8
+ // Read the first 4 bytes as the message type
9
+ this._view = new DataView(buffer);
10
+ this.type = this.readInt32();
11
+ }
12
+ readInt32() {
13
+ const value = this._view.getInt32(this._offset, true);
14
+ this._offset += 4;
15
+ return value;
16
+ }
17
+ }
@@ -0,0 +1,4 @@
1
+ export declare enum WsMessageType {
2
+ SubscribeReq = 1,
3
+ SubscribeRes = 2
4
+ }
@@ -0,0 +1,5 @@
1
+ export var WsMessageType;
2
+ (function (WsMessageType) {
3
+ WsMessageType[WsMessageType["SubscribeReq"] = 1] = "SubscribeReq";
4
+ WsMessageType[WsMessageType["SubscribeRes"] = 2] = "SubscribeRes";
5
+ })(WsMessageType || (WsMessageType = {}));
@@ -0,0 +1,12 @@
1
+ import type { WsMessageType } from "./ws-message-type";
2
+ export declare class WsMessageWriter {
3
+ type: WsMessageType;
4
+ payloadLength: number;
5
+ private _buffer;
6
+ private _view;
7
+ private _offset;
8
+ constructor(type: WsMessageType, payloadLength: number);
9
+ writeInt32(value: number): void;
10
+ writeString(value: string): void;
11
+ get buffer(): ArrayBuffer;
12
+ }
@@ -0,0 +1,30 @@
1
+ export class WsMessageWriter {
2
+ type;
3
+ payloadLength;
4
+ _buffer;
5
+ _view;
6
+ _offset = 0;
7
+ constructor(type, payloadLength) {
8
+ this.type = type;
9
+ this.payloadLength = payloadLength;
10
+ this._buffer = new ArrayBuffer(4 + payloadLength);
11
+ this._view = new DataView(this._buffer);
12
+ // Write type
13
+ this.writeInt32(type);
14
+ }
15
+ writeInt32(value) {
16
+ this._view.setInt32(this._offset, value, true);
17
+ this._offset += 4;
18
+ }
19
+ writeString(value) {
20
+ // Write length
21
+ this.writeInt32(value.length);
22
+ // Write chars
23
+ for (let i = 0; i < value.length; i++) {
24
+ this._view.setUint8(this._offset++, value.charCodeAt(i));
25
+ }
26
+ }
27
+ get buffer() {
28
+ return this._buffer;
29
+ }
30
+ }