@replicast/core 0.1.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 (49) hide show
  1. package/dist/decorators/index.d.ts +5 -0
  2. package/dist/decorators/index.d.ts.map +1 -0
  3. package/dist/decorators/index.js +4 -0
  4. package/dist/decorators/index.js.map +1 -0
  5. package/dist/decorators/metadata.d.ts +14 -0
  6. package/dist/decorators/metadata.d.ts.map +1 -0
  7. package/dist/decorators/metadata.js +25 -0
  8. package/dist/decorators/metadata.js.map +1 -0
  9. package/dist/decorators/store.d.ts +9 -0
  10. package/dist/decorators/store.d.ts.map +1 -0
  11. package/dist/decorators/store.js +18 -0
  12. package/dist/decorators/store.js.map +1 -0
  13. package/dist/decorators/system.d.ts +11 -0
  14. package/dist/decorators/system.d.ts.map +1 -0
  15. package/dist/decorators/system.js +35 -0
  16. package/dist/decorators/system.js.map +1 -0
  17. package/dist/index.d.ts +16 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +15 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/lifecycle/base-client.d.ts +8 -0
  22. package/dist/lifecycle/base-client.d.ts.map +1 -0
  23. package/dist/lifecycle/base-client.js +9 -0
  24. package/dist/lifecycle/base-client.js.map +1 -0
  25. package/dist/lifecycle/base-server.d.ts +7 -0
  26. package/dist/lifecycle/base-server.d.ts.map +1 -0
  27. package/dist/lifecycle/base-server.js +9 -0
  28. package/dist/lifecycle/base-server.js.map +1 -0
  29. package/dist/lifecycle/types.d.ts +15 -0
  30. package/dist/lifecycle/types.d.ts.map +1 -0
  31. package/dist/lifecycle/types.js +2 -0
  32. package/dist/lifecycle/types.js.map +1 -0
  33. package/dist/store/base-store.d.ts +25 -0
  34. package/dist/store/base-store.d.ts.map +1 -0
  35. package/dist/store/base-store.js +113 -0
  36. package/dist/store/base-store.js.map +1 -0
  37. package/dist/transport/client.d.ts +58 -0
  38. package/dist/transport/client.d.ts.map +1 -0
  39. package/dist/transport/client.js +261 -0
  40. package/dist/transport/client.js.map +1 -0
  41. package/dist/transport/protocol.d.ts +66 -0
  42. package/dist/transport/protocol.d.ts.map +1 -0
  43. package/dist/transport/protocol.js +27 -0
  44. package/dist/transport/protocol.js.map +1 -0
  45. package/dist/transport/server.d.ts +24 -0
  46. package/dist/transport/server.d.ts.map +1 -0
  47. package/dist/transport/server.js +191 -0
  48. package/dist/transport/server.js.map +1 -0
  49. package/package.json +24 -0
@@ -0,0 +1,5 @@
1
+ export { GlobalStore, OwnerStore, Global, OwnerOnly, ServerOnly } from './store.js';
2
+ export { System, Server, Client, Multicast, isSystemKey, isServerClassKey, isClientClassKey } from './system.js';
3
+ export { getStoreType, getPropertyRoles, getMethodRoles } from './metadata.js';
4
+ export type { StoreType, PropertyRole, MethodRole } from './metadata.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9E,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { GlobalStore, OwnerStore, Global, OwnerOnly, ServerOnly } from './store.js';
2
+ export { System, Server, Client, Multicast, isSystemKey, isServerClassKey, isClientClassKey } from './system.js';
3
+ export { getStoreType, getPropertyRoles, getMethodRoles } from './metadata.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAChH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,14 @@
1
+ import 'reflect-metadata';
2
+ export declare const storeTypeKey: unique symbol;
3
+ export declare const propertyRolesKey: unique symbol;
4
+ export declare const methodRolesKey: unique symbol;
5
+ export type StoreType = 'global' | 'owner';
6
+ export type PropertyRole = 'global' | 'ownerOnly' | 'serverOnly';
7
+ export type MethodRole = 'server' | 'client' | 'multicast';
8
+ export declare function getStoreType(target: Function): StoreType | undefined;
9
+ export declare function setStoreType(target: Function, type: StoreType): void;
10
+ export declare function getPropertyRoles(proto: object): Record<string, PropertyRole>;
11
+ export declare function setPropertyRole(proto: object, key: string, role: PropertyRole): void;
12
+ export declare function getMethodRoles(proto: object): Record<string, MethodRole>;
13
+ export declare function setMethodRole(proto: object, key: string, role: MethodRole): void;
14
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/decorators/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AAEzB,eAAO,MAAM,YAAY,eAAgC,CAAA;AACzD,eAAO,MAAM,gBAAgB,eAAoC,CAAA;AACjE,eAAO,MAAM,cAAc,eAAkC,CAAA;AAE7D,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AAC1C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,CAAA;AAChE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;AAE1D,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAEpE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAEpE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAE5E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAGpF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAExE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAGhF"}
@@ -0,0 +1,25 @@
1
+ import 'reflect-metadata';
2
+ export const storeTypeKey = Symbol('replicast:storeType');
3
+ export const propertyRolesKey = Symbol('replicast:propertyRoles');
4
+ export const methodRolesKey = Symbol('replicast:methodRoles');
5
+ export function getStoreType(target) {
6
+ return Reflect.getMetadata(storeTypeKey, target);
7
+ }
8
+ export function setStoreType(target, type) {
9
+ Reflect.defineMetadata(storeTypeKey, type, target);
10
+ }
11
+ export function getPropertyRoles(proto) {
12
+ return Reflect.getMetadata(propertyRolesKey, proto) ?? {};
13
+ }
14
+ export function setPropertyRole(proto, key, role) {
15
+ const existing = getPropertyRoles(proto);
16
+ Reflect.defineMetadata(propertyRolesKey, { ...existing, [key]: role }, proto);
17
+ }
18
+ export function getMethodRoles(proto) {
19
+ return Reflect.getMetadata(methodRolesKey, proto) ?? {};
20
+ }
21
+ export function setMethodRole(proto, key, role) {
22
+ const existing = getMethodRoles(proto);
23
+ Reflect.defineMetadata(methodRolesKey, { ...existing, [key]: role }, proto);
24
+ }
25
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/decorators/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AAEzB,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAA;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAA;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAA;AAM7D,MAAM,UAAU,YAAY,CAAC,MAAgB;IAC3C,OAAO,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAgB,EAAE,IAAe;IAC5D,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AACpD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,EAAE,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,GAAW,EAAE,IAAkB;IAC5E,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACxC,OAAO,CAAC,cAAc,CAAC,gBAAgB,EAAE,EAAE,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;AAC/E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE,KAAK,CAAC,IAAI,EAAE,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAW,EAAE,IAAgB;IACxE,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACtC,OAAO,CAAC,cAAc,CAAC,cAAc,EAAE,EAAE,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;AAC7E,CAAC"}
@@ -0,0 +1,9 @@
1
+ import 'reflect-metadata';
2
+ type AnyConstructor = new (...args: any[]) => object;
3
+ export declare function GlobalStore(target: AnyConstructor): void;
4
+ export declare function OwnerStore(target: AnyConstructor): void;
5
+ export declare function Global(target: object, propertyKey: string): void;
6
+ export declare function OwnerOnly(target: object, propertyKey: string): void;
7
+ export declare function ServerOnly(target: object, propertyKey: string): void;
8
+ export {};
9
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/decorators/store.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AAGzB,KAAK,cAAc,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAA;AAEpD,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAExD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAEvD;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAEhE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAEnE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAEpE"}
@@ -0,0 +1,18 @@
1
+ import 'reflect-metadata';
2
+ import { setStoreType, setPropertyRole } from './metadata.js';
3
+ export function GlobalStore(target) {
4
+ setStoreType(target, 'global');
5
+ }
6
+ export function OwnerStore(target) {
7
+ setStoreType(target, 'owner');
8
+ }
9
+ export function Global(target, propertyKey) {
10
+ setPropertyRole(target, propertyKey, 'global');
11
+ }
12
+ export function OwnerOnly(target, propertyKey) {
13
+ setPropertyRole(target, propertyKey, 'ownerOnly');
14
+ }
15
+ export function ServerOnly(target, propertyKey) {
16
+ setPropertyRole(target, propertyKey, 'serverOnly');
17
+ }
18
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/decorators/store.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAI7D,MAAM,UAAU,WAAW,CAAC,MAAsB;IAChD,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,WAAmB;IACxD,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,WAAmB;IAC3D,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,WAAmB;IAC5D,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,CAAA;AACpD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import 'reflect-metadata';
2
+ declare const isSystemKey: unique symbol;
3
+ declare const isServerClassKey: unique symbol;
4
+ declare const isClientClassKey: unique symbol;
5
+ type AnyConstructor = new (...args: any[]) => object;
6
+ export declare function System(target: AnyConstructor): void;
7
+ export declare function Server(target: object | AnyConstructor, propertyKey?: string): void;
8
+ export declare function Client(target: object | AnyConstructor, propertyKey?: string): void;
9
+ export declare function Multicast(target: object, propertyKey: string): void;
10
+ export { isSystemKey, isServerClassKey, isClientClassKey };
11
+ //# sourceMappingURL=system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/decorators/system.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AAGzB,QAAA,MAAM,WAAW,eAAmC,CAAA;AACpD,QAAA,MAAM,gBAAgB,eAAwC,CAAA;AAC9D,QAAA,MAAM,gBAAgB,eAAwC,CAAA;AAE9D,KAAK,cAAc,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAA;AAEpD,wBAAgB,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAEnD;AAID,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAQlF;AAID,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAMlF;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAEnE;AAED,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}
@@ -0,0 +1,35 @@
1
+ import 'reflect-metadata';
2
+ import { setMethodRole } from './metadata.js';
3
+ const isSystemKey = Symbol.for('replicast:isSystem');
4
+ const isServerClassKey = Symbol.for('replicast:isServerClass');
5
+ const isClientClassKey = Symbol.for('replicast:isClientClass');
6
+ export function System(target) {
7
+ Reflect.defineMetadata(isSystemKey, true, target);
8
+ }
9
+ // @Server on a method: marks it as a server-side RPC
10
+ // @Server on a class: marks it as a server-only lifecycle class
11
+ export function Server(target, propertyKey) {
12
+ if (propertyKey === undefined) {
13
+ // Class decorator
14
+ Reflect.defineMetadata(isServerClassKey, true, target);
15
+ }
16
+ else {
17
+ // Method decorator
18
+ setMethodRole(target, propertyKey, 'server');
19
+ }
20
+ }
21
+ // @Client on a method: marks it as a client-side RPC
22
+ // @Client on a class: marks it as a client-only lifecycle class
23
+ export function Client(target, propertyKey) {
24
+ if (propertyKey === undefined) {
25
+ Reflect.defineMetadata(isClientClassKey, true, target);
26
+ }
27
+ else {
28
+ setMethodRole(target, propertyKey, 'client');
29
+ }
30
+ }
31
+ export function Multicast(target, propertyKey) {
32
+ setMethodRole(target, propertyKey, 'multicast');
33
+ }
34
+ export { isSystemKey, isServerClassKey, isClientClassKey };
35
+ //# sourceMappingURL=system.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/decorators/system.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;AACpD,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;AAC9D,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;AAI9D,MAAM,UAAU,MAAM,CAAC,MAAsB;IAC3C,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AACnD,CAAC;AAED,qDAAqD;AACrD,gEAAgE;AAChE,MAAM,UAAU,MAAM,CAAC,MAA+B,EAAE,WAAoB;IAC1E,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,kBAAkB;QAClB,OAAO,CAAC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,MAAwB,CAAC,CAAA;IAC1E,CAAC;SAAM,CAAC;QACN,mBAAmB;QACnB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;IAC9C,CAAC;AACH,CAAC;AAED,qDAAqD;AACrD,gEAAgE;AAChE,MAAM,UAAU,MAAM,CAAC,MAA+B,EAAE,WAAoB;IAC1E,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,MAAwB,CAAC,CAAA;IAC1E,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;IAC9C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,WAAmB;IAC3D,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AACjD,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}
@@ -0,0 +1,16 @@
1
+ import 'reflect-metadata';
2
+ export { GlobalStore, OwnerStore, Global, OwnerOnly, ServerOnly } from './decorators/store.js';
3
+ export { System, Server, Client, Multicast } from './decorators/system.js';
4
+ export { getStoreType, getPropertyRoles, getMethodRoles, setPropertyRole, setMethodRole } from './decorators/metadata.js';
5
+ export type { StoreType, PropertyRole, MethodRole } from './decorators/metadata.js';
6
+ export { BaseStore } from './store/base-store.js';
7
+ export type { ReplicationBatch } from './store/base-store.js';
8
+ export type { ConnectRequest, ConnectPayload, ServerContext } from './lifecycle/types.js';
9
+ export { BaseServerLifecycle } from './lifecycle/base-server.js';
10
+ export { BaseClientLifecycle } from './lifecycle/base-client.js';
11
+ export { createRPCServer } from './transport/server.js';
12
+ export type { RpcServer } from './transport/server.js';
13
+ export { ConnectionLostError, AuthRejectedError, RpcError, TimeoutError } from './transport/protocol.js';
14
+ export { WsClient } from './transport/client.js';
15
+ export type { ConnectionStatus, ConnectionQuality, WsClientOptions, LatencyThresholds } from './transport/client.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AAGzB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAC9F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACzH,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAGnF,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAG7D,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAGhE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACxG,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ import 'reflect-metadata';
2
+ // Decorators
3
+ export { GlobalStore, OwnerStore, Global, OwnerOnly, ServerOnly } from './decorators/store.js';
4
+ export { System, Server, Client, Multicast } from './decorators/system.js';
5
+ export { getStoreType, getPropertyRoles, getMethodRoles, setPropertyRole, setMethodRole } from './decorators/metadata.js';
6
+ // Store
7
+ export { BaseStore } from './store/base-store.js';
8
+ // Lifecycle base classes
9
+ export { BaseServerLifecycle } from './lifecycle/base-server.js';
10
+ export { BaseClientLifecycle } from './lifecycle/base-client.js';
11
+ // Transport (exported in tasks 8 and 9)
12
+ export { createRPCServer } from './transport/server.js';
13
+ export { ConnectionLostError, AuthRejectedError, RpcError, TimeoutError } from './transport/protocol.js';
14
+ export { WsClient } from './transport/client.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAA;AAEzB,aAAa;AACb,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAC9F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAGzH,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAMjD,yBAAyB;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAEhE,wCAAwC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACxG,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { ConnectPayload } from './types.js';
2
+ export declare class BaseClientLifecycle {
3
+ onConnect(): Promise<ConnectPayload>;
4
+ onConnected(): Promise<void>;
5
+ onDisconnected(): Promise<void>;
6
+ onAuthFailed(): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=base-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-client.d.ts","sourceRoot":"","sources":["../../src/lifecycle/base-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,qBAAa,mBAAmB;IACxB,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAIpC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAE5B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAE/B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CACpC"}
@@ -0,0 +1,9 @@
1
+ export class BaseClientLifecycle {
2
+ async onConnect() {
3
+ return {};
4
+ }
5
+ async onConnected() { }
6
+ async onDisconnected() { }
7
+ async onAuthFailed() { }
8
+ }
9
+ //# sourceMappingURL=base-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-client.js","sourceRoot":"","sources":["../../src/lifecycle/base-client.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,SAAS;QACb,OAAO,EAAE,CAAA;IACX,CAAC;IAED,KAAK,CAAC,WAAW,KAAmB,CAAC;IAErC,KAAK,CAAC,cAAc,KAAmB,CAAC;IAExC,KAAK,CAAC,YAAY,KAAmB,CAAC;CACvC"}
@@ -0,0 +1,7 @@
1
+ import type { ConnectRequest, ServerContext } from './types.js';
2
+ export declare class BaseServerLifecycle {
3
+ onConnect(_req: ConnectRequest): Promise<string | null>;
4
+ onPlayerJoined(_ctx: ServerContext): Promise<void>;
5
+ onPlayerLeft(_ctx: ServerContext): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=base-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-server.d.ts","sourceRoot":"","sources":["../../src/lifecycle/base-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/D,qBAAa,mBAAmB;IACxB,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIvD,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAElD,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CACvD"}
@@ -0,0 +1,9 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ export class BaseServerLifecycle {
3
+ async onConnect(_req) {
4
+ return uuidv4();
5
+ }
6
+ async onPlayerJoined(_ctx) { }
7
+ async onPlayerLeft(_ctx) { }
8
+ }
9
+ //# sourceMappingURL=base-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-server.js","sourceRoot":"","sources":["../../src/lifecycle/base-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAA;AAGnC,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,SAAS,CAAC,IAAoB;QAClC,OAAO,MAAM,EAAE,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAmB,IAAkB,CAAC;IAE3D,KAAK,CAAC,YAAY,CAAC,IAAmB,IAAkB,CAAC;CAC1D"}
@@ -0,0 +1,15 @@
1
+ export interface ConnectRequest {
2
+ headers: Record<string, string | string[] | undefined>;
3
+ url: string;
4
+ payload: Record<string, unknown>;
5
+ }
6
+ export interface ConnectPayload {
7
+ token?: string;
8
+ [key: string]: unknown;
9
+ }
10
+ export interface ServerContext {
11
+ playerId: string;
12
+ players: string[];
13
+ sendToClient(playerId: string, method: string, ...args: unknown[]): void;
14
+ }
15
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lifecycle/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IACtD,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CACzE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lifecycle/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ export interface OwnerPatch {
2
+ seq: number;
3
+ patch: Record<string, unknown>;
4
+ }
5
+ export interface ReplicationBatch {
6
+ globalSeq: number;
7
+ global: Record<string, unknown>;
8
+ ownerByPlayer: Map<string, OwnerPatch>;
9
+ }
10
+ export declare class BaseStore {
11
+ private _ownerData;
12
+ private _dirtyGlobal;
13
+ private _dirtyOwner;
14
+ private _flushScheduled;
15
+ private _globalSeq;
16
+ private _ownerSeqs;
17
+ _onReplication?: (batch: ReplicationBatch) => void;
18
+ set(partial: Record<string, unknown>): void;
19
+ setOwner(key: string, playerId: string, value: unknown): void;
20
+ getOwner<T>(key: string, playerId: string): T;
21
+ getSnapshot(playerId?: string): Record<string, unknown>;
22
+ private _scheduleFlush;
23
+ private _flush;
24
+ }
25
+ //# sourceMappingURL=base-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-store.d.ts","sourceRoot":"","sources":["../../src/store/base-store.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CACvC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,UAAU,CAA4B;IAE9C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAElD,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAqB3C,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAgB7D,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC;IAI7C,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAcvD,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,MAAM;CAuCf"}
@@ -0,0 +1,113 @@
1
+ import { getPropertyRoles, getStoreType } from '../decorators/metadata.js';
2
+ export class BaseStore {
3
+ _ownerData = new Map();
4
+ _dirtyGlobal = new Set();
5
+ _dirtyOwner = new Map();
6
+ _flushScheduled = false;
7
+ _globalSeq = 0;
8
+ _ownerSeqs = new Map(); // playerId → seq
9
+ _onReplication;
10
+ set(partial) {
11
+ if (getStoreType(Object.getPrototypeOf(this).constructor) === 'owner') {
12
+ throw new Error('@OwnerStore does not support set(). Use setOwner() for all properties.');
13
+ }
14
+ const roles = getPropertyRoles(Object.getPrototypeOf(this));
15
+ for (const [key, value] of Object.entries(partial)) {
16
+ const role = roles[key];
17
+ if (role === 'ownerOnly') {
18
+ throw new Error(`Use setOwner() for @OwnerOnly property "${key}"`);
19
+ }
20
+ if (role === undefined) {
21
+ throw new Error(`Unknown property "${key}" — must be decorated with @Global, @ServerOnly, or @OwnerOnly`);
22
+ }
23
+ ;
24
+ this[key] = value;
25
+ if (role === 'global') {
26
+ this._dirtyGlobal.add(key);
27
+ this._scheduleFlush();
28
+ }
29
+ }
30
+ }
31
+ setOwner(key, playerId, value) {
32
+ const roles = getPropertyRoles(Object.getPrototypeOf(this));
33
+ const role = roles[key];
34
+ if (role === undefined) {
35
+ throw new Error(`Unknown property "${key}" — must be decorated with @Global, @ServerOnly, or @OwnerOnly`);
36
+ }
37
+ if (role !== 'ownerOnly') {
38
+ throw new Error(`Use set() for @${role === 'global' ? 'Global' : 'ServerOnly'} property "${key}"`);
39
+ }
40
+ if (!this._ownerData.has(key))
41
+ this._ownerData.set(key, new Map());
42
+ this._ownerData.get(key).set(playerId, value);
43
+ if (!this._dirtyOwner.has(key))
44
+ this._dirtyOwner.set(key, new Set());
45
+ this._dirtyOwner.get(key).add(playerId);
46
+ this._scheduleFlush();
47
+ }
48
+ getOwner(key, playerId) {
49
+ return this._ownerData.get(key)?.get(playerId);
50
+ }
51
+ getSnapshot(playerId) {
52
+ const roles = getPropertyRoles(Object.getPrototypeOf(this));
53
+ const snapshot = {};
54
+ for (const [key, role] of Object.entries(roles)) {
55
+ if (role === 'global') {
56
+ snapshot[key] = this[key];
57
+ }
58
+ else if (role === 'ownerOnly' && playerId != null) {
59
+ const ownerValue = this._ownerData.get(key)?.get(playerId);
60
+ if (ownerValue !== undefined)
61
+ snapshot[key] = ownerValue;
62
+ }
63
+ }
64
+ return snapshot;
65
+ }
66
+ _scheduleFlush() {
67
+ if (this._flushScheduled)
68
+ return;
69
+ this._flushScheduled = true;
70
+ process.nextTick(() => {
71
+ this._flushScheduled = false;
72
+ this._flush();
73
+ });
74
+ }
75
+ _flush() {
76
+ if (!this._onReplication) {
77
+ // Nobody listening yet — discard dirty state so it doesn't accumulate
78
+ // and leak into the first incremental patch after _onReplication is set.
79
+ // (getSnapshot() provides the full initial state on connect.)
80
+ this._dirtyGlobal.clear();
81
+ this._dirtyOwner.clear();
82
+ return;
83
+ }
84
+ const batch = { globalSeq: 0, global: {}, ownerByPlayer: new Map() };
85
+ if (this._dirtyGlobal.size > 0) {
86
+ this._globalSeq++;
87
+ batch.globalSeq = this._globalSeq;
88
+ for (const key of this._dirtyGlobal) {
89
+ batch.global[key] = this[key];
90
+ }
91
+ this._dirtyGlobal.clear();
92
+ }
93
+ if (this._dirtyOwner.size > 0) {
94
+ // Invert from key→{playerId→value} into playerId→{key→value} with per-player seq
95
+ const byPlayer = new Map();
96
+ for (const [key, playerIds] of this._dirtyOwner) {
97
+ for (const playerId of playerIds) {
98
+ if (!byPlayer.has(playerId))
99
+ byPlayer.set(playerId, {});
100
+ byPlayer.get(playerId)[key] = this._ownerData.get(key)?.get(playerId);
101
+ }
102
+ }
103
+ for (const [playerId, patch] of byPlayer) {
104
+ const seq = (this._ownerSeqs.get(playerId) ?? 0) + 1;
105
+ this._ownerSeqs.set(playerId, seq);
106
+ batch.ownerByPlayer.set(playerId, { seq, patch });
107
+ }
108
+ this._dirtyOwner.clear();
109
+ }
110
+ this._onReplication(batch);
111
+ }
112
+ }
113
+ //# sourceMappingURL=base-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-store.js","sourceRoot":"","sources":["../../src/store/base-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { BaseClientLifecycle } from '../lifecycle/base-client.js';
2
+ import { BaseStore } from '../store/base-store.js';
3
+ interface StoreRegistration {
4
+ name: string;
5
+ instance: BaseStore;
6
+ }
7
+ export interface LatencyThresholds {
8
+ good: number;
9
+ fair: number;
10
+ }
11
+ export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
12
+ export type ConnectionQuality = 'good' | 'fair' | 'poor';
13
+ export interface WsClientOptions {
14
+ url: string;
15
+ stores: StoreRegistration[];
16
+ systems: object[];
17
+ lifecycle: BaseClientLifecycle;
18
+ latencyThresholds?: LatencyThresholds;
19
+ pingInterval?: number;
20
+ rpcTimeout?: number;
21
+ }
22
+ export declare class WsClient {
23
+ private options;
24
+ private ws?;
25
+ private pendingCalls;
26
+ private shouldReconnect;
27
+ private reconnectAttempt;
28
+ private readonly maxDelay;
29
+ private readonly baseDelay;
30
+ private pingTimer?;
31
+ private pendingPings;
32
+ private readonly thresholds;
33
+ private readonly pingInterval;
34
+ latency: number | null;
35
+ quality: ConnectionQuality | null;
36
+ playerId: string | null;
37
+ onStatusChange?: (status: ConnectionStatus) => void;
38
+ onLatencyChange?: (latency: number, quality: ConnectionQuality) => void;
39
+ private lastSeq;
40
+ private expectedStoreCount;
41
+ private receivedStoreCount;
42
+ private readonly rpcTimeout;
43
+ constructor(options: WsClientOptions);
44
+ private encode;
45
+ private decode;
46
+ private getDelay;
47
+ private rejectPending;
48
+ private startPinging;
49
+ private stopPinging;
50
+ private computeQuality;
51
+ private applyMessage;
52
+ private openConnection;
53
+ connect(): Promise<void>;
54
+ call(method: string, args: unknown[]): Promise<unknown>;
55
+ disconnect(): Promise<void>;
56
+ }
57
+ export {};
58
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/transport/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAKlD,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAA;AAC3F,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAExD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,mBAAmB,CAAA;IAC9B,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,QAAQ;IAuBP,OAAO,CAAC,OAAO;IAtB3B,OAAO,CAAC,EAAE,CAAC,CAAW;IACtB,OAAO,CAAC,YAAY,CAAmF;IACvG,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IAErC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAO;IAC7B,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAO;IACxC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAO;IAC9B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACnD,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAEvE,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;gBAEf,OAAO,EAAE,eAAe;IAM5C,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAiHpB,OAAO,CAAC,cAAc;IAsCtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBvD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ5B"}
@@ -0,0 +1,261 @@
1
+ import WebSocket from 'ws';
2
+ import { ConnectionLostError, AuthRejectedError, RpcError, TimeoutError } from './protocol.js';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ export class WsClient {
5
+ options;
6
+ ws;
7
+ pendingCalls = new Map();
8
+ shouldReconnect = false;
9
+ reconnectAttempt = 0;
10
+ maxDelay = 30_000;
11
+ baseDelay = 1_000;
12
+ pingTimer;
13
+ pendingPings = new Map(); // id → sent timestamp
14
+ thresholds;
15
+ pingInterval;
16
+ latency = null;
17
+ quality = null;
18
+ playerId = null;
19
+ onStatusChange;
20
+ onLatencyChange;
21
+ lastSeq = new Map(); // key: `${store}:${scope}`
22
+ expectedStoreCount = 0;
23
+ receivedStoreCount = 0;
24
+ rpcTimeout;
25
+ constructor(options) {
26
+ this.options = options;
27
+ this.thresholds = options.latencyThresholds ?? { good: 100, fair: 300 };
28
+ this.pingInterval = options.pingInterval ?? 5_000;
29
+ this.rpcTimeout = options.rpcTimeout ?? 30_000;
30
+ }
31
+ encode(msg) {
32
+ return JSON.stringify(msg);
33
+ }
34
+ decode(raw) {
35
+ return JSON.parse(raw.toString());
36
+ }
37
+ getDelay() {
38
+ const delay = Math.min(this.baseDelay * Math.pow(2, this.reconnectAttempt), this.maxDelay);
39
+ return delay * (0.9 + Math.random() * 0.2);
40
+ }
41
+ rejectPending() {
42
+ for (const { reject } of this.pendingCalls.values()) {
43
+ reject(new ConnectionLostError());
44
+ }
45
+ this.pendingCalls.clear();
46
+ }
47
+ startPinging() {
48
+ this.pingTimer = setInterval(() => {
49
+ if (this.ws?.readyState !== WebSocket.OPEN)
50
+ return;
51
+ const id = uuidv4();
52
+ this.pendingPings.set(id, Date.now());
53
+ this.ws.send(this.encode({ type: 'ping', id }));
54
+ }, this.pingInterval);
55
+ }
56
+ stopPinging() {
57
+ if (this.pingTimer) {
58
+ clearInterval(this.pingTimer);
59
+ this.pingTimer = undefined;
60
+ }
61
+ this.pendingPings.clear();
62
+ }
63
+ computeQuality(rtt) {
64
+ if (rtt < this.thresholds.good)
65
+ return 'good';
66
+ if (rtt < this.thresholds.fair)
67
+ return 'fair';
68
+ return 'poor';
69
+ }
70
+ applyMessage(msg, resolve, reject) {
71
+ const { stores, systems, lifecycle } = this.options;
72
+ if (msg.type === 'auth_rejected') {
73
+ // Prevent reconnect loop after auth rejection
74
+ this.shouldReconnect = false;
75
+ lifecycle.onAuthFailed()
76
+ .then(() => reject(new AuthRejectedError()))
77
+ .catch((e) => reject(e));
78
+ return;
79
+ }
80
+ if (msg.type === 'connected') {
81
+ this.playerId = msg.playerId;
82
+ this.expectedStoreCount = msg.storeCount;
83
+ this.receivedStoreCount = 0;
84
+ // If no stores, resolve immediately
85
+ if (msg.storeCount === 0) {
86
+ lifecycle.onConnected().then(() => {
87
+ this.reconnectAttempt = 0;
88
+ this.onStatusChange?.('connected');
89
+ this.startPinging();
90
+ resolve();
91
+ }).catch(e => reject(e));
92
+ }
93
+ return;
94
+ }
95
+ if (msg.type === 'state_init') {
96
+ // Reset seq tracking for this store — snapshot is authoritative
97
+ this.lastSeq.delete(`${msg.store}:global`);
98
+ this.lastSeq.delete(`${msg.store}:owner`);
99
+ const store = stores.find(s => s.name === msg.store);
100
+ if (store) {
101
+ for (const [key, value] of Object.entries(msg.snapshot)) {
102
+ ;
103
+ store.instance[key] = value;
104
+ }
105
+ if (typeof store.instance._onReplication === 'function') {
106
+ ;
107
+ store.instance._onReplication({
108
+ globalSeq: 0,
109
+ global: msg.snapshot,
110
+ ownerByPlayer: new Map()
111
+ });
112
+ }
113
+ }
114
+ this.receivedStoreCount++;
115
+ // Resolve only after ALL stores have been initialised
116
+ if (this.receivedStoreCount >= this.expectedStoreCount) {
117
+ lifecycle.onConnected().then(() => {
118
+ this.reconnectAttempt = 0;
119
+ this.onStatusChange?.('connected');
120
+ this.startPinging();
121
+ resolve();
122
+ }).catch(e => reject(e));
123
+ }
124
+ return;
125
+ }
126
+ if (msg.type === 'state_patch') {
127
+ // Enforce ordering: drop stale patches silently
128
+ const seqKey = `${msg.store}:${msg.scope}`;
129
+ const lastSeq = this.lastSeq.get(seqKey) ?? 0;
130
+ if (msg.seq <= lastSeq)
131
+ return;
132
+ this.lastSeq.set(seqKey, msg.seq);
133
+ const store = stores.find(s => s.name === msg.store);
134
+ if (store) {
135
+ for (const [key, value] of Object.entries(msg.patch)) {
136
+ ;
137
+ store.instance[key] = value;
138
+ }
139
+ if (typeof store.instance._onReplication === 'function') {
140
+ const batch = {
141
+ globalSeq: msg.scope === 'global' ? msg.seq : 0,
142
+ global: msg.scope === 'global' ? msg.patch : {},
143
+ ownerByPlayer: msg.scope === 'owner'
144
+ ? new Map([[this.playerId, { seq: msg.seq, patch: msg.patch }]])
145
+ : new Map()
146
+ };
147
+ store.instance._onReplication(batch);
148
+ }
149
+ }
150
+ return;
151
+ }
152
+ if (msg.type === 'rpc') {
153
+ const methodName = msg.method.split('.')[1];
154
+ for (const system of systems) {
155
+ if (typeof system[methodName] === 'function') {
156
+ ;
157
+ system[methodName](...msg.args);
158
+ }
159
+ }
160
+ return;
161
+ }
162
+ if (msg.type === 'rpc_result') {
163
+ const pending = this.pendingCalls.get(msg.id);
164
+ if (!pending)
165
+ return;
166
+ this.pendingCalls.delete(msg.id);
167
+ if (msg.error)
168
+ pending.reject(new RpcError(msg.error));
169
+ else
170
+ pending.resolve(msg.result);
171
+ return;
172
+ }
173
+ if (msg.type === 'pong') {
174
+ const sent = this.pendingPings.get(msg.id);
175
+ if (sent === undefined)
176
+ return;
177
+ this.pendingPings.delete(msg.id);
178
+ const rtt = Date.now() - sent;
179
+ this.latency = rtt;
180
+ this.quality = this.computeQuality(rtt);
181
+ this.onLatencyChange?.(rtt, this.quality);
182
+ }
183
+ }
184
+ openConnection() {
185
+ return new Promise((resolve, reject) => {
186
+ const { url, lifecycle } = this.options;
187
+ this.ws = new WebSocket(url);
188
+ this.ws.on('error', reject);
189
+ this.ws.on('open', async () => {
190
+ const payload = await lifecycle.onConnect();
191
+ this.ws.send(this.encode({ type: 'auth', payload }));
192
+ });
193
+ this.ws.on('message', (raw) => {
194
+ let msg;
195
+ try {
196
+ msg = this.decode(raw);
197
+ }
198
+ catch {
199
+ return;
200
+ }
201
+ this.applyMessage(msg, resolve, reject);
202
+ });
203
+ this.ws.on('close', async () => {
204
+ this.stopPinging();
205
+ this.rejectPending();
206
+ await lifecycle.onDisconnected();
207
+ if (this.shouldReconnect) {
208
+ this.reconnectAttempt++;
209
+ this.onStatusChange?.('reconnecting');
210
+ setTimeout(() => {
211
+ if (this.shouldReconnect) {
212
+ this.onStatusChange?.('connecting');
213
+ this.openConnection().catch(() => { });
214
+ }
215
+ }, this.getDelay());
216
+ }
217
+ else {
218
+ this.onStatusChange?.('disconnected');
219
+ }
220
+ });
221
+ });
222
+ }
223
+ connect() {
224
+ this.shouldReconnect = true;
225
+ this.reconnectAttempt = 0;
226
+ this.onStatusChange?.('connecting');
227
+ return this.openConnection();
228
+ }
229
+ call(method, args) {
230
+ return new Promise((resolve, reject) => {
231
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
232
+ reject(new Error('Not connected'));
233
+ return;
234
+ }
235
+ const id = uuidv4();
236
+ const timer = setTimeout(() => {
237
+ if (this.pendingCalls.has(id)) {
238
+ this.pendingCalls.delete(id);
239
+ reject(new TimeoutError());
240
+ }
241
+ }, this.rpcTimeout);
242
+ this.pendingCalls.set(id, {
243
+ resolve: (v) => { clearTimeout(timer); resolve(v); },
244
+ reject: (e) => { clearTimeout(timer); reject(e); },
245
+ });
246
+ this.ws.send(this.encode({ type: 'rpc', method, args, id }));
247
+ });
248
+ }
249
+ disconnect() {
250
+ this.shouldReconnect = false;
251
+ return new Promise(resolve => {
252
+ if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
253
+ resolve();
254
+ return;
255
+ }
256
+ this.ws.once('close', () => resolve());
257
+ this.ws.close();
258
+ });
259
+ }
260
+ }
261
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/transport/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ export interface RpcCallMessage {
2
+ type: 'rpc';
3
+ method: string;
4
+ args: unknown[];
5
+ id: string;
6
+ }
7
+ export interface RpcResultMessage {
8
+ type: 'rpc_result';
9
+ id: string;
10
+ result?: unknown;
11
+ error?: string;
12
+ }
13
+ export interface RpcPushMessage {
14
+ type: 'rpc';
15
+ method: string;
16
+ args: unknown[];
17
+ }
18
+ export interface StateInitMessage {
19
+ type: 'state_init';
20
+ store: string;
21
+ snapshot: Record<string, unknown>;
22
+ }
23
+ export interface StatePatchMessage {
24
+ type: 'state_patch';
25
+ store: string;
26
+ scope: 'global' | 'owner';
27
+ seq: number;
28
+ patch: Record<string, unknown>;
29
+ }
30
+ export interface AuthPayloadMessage {
31
+ type: 'auth';
32
+ payload: Record<string, unknown>;
33
+ }
34
+ export interface AuthRejectedMessage {
35
+ type: 'auth_rejected';
36
+ reason?: string;
37
+ }
38
+ export interface ConnectedMessage {
39
+ type: 'connected';
40
+ playerId: string;
41
+ storeCount: number;
42
+ }
43
+ export interface PingMessage {
44
+ type: 'ping';
45
+ id: string;
46
+ }
47
+ export interface PongMessage {
48
+ type: 'pong';
49
+ id: string;
50
+ }
51
+ export type ClientToServerMessage = RpcCallMessage | AuthPayloadMessage | PingMessage;
52
+ export type ServerToClientMessage = ConnectedMessage | RpcResultMessage | RpcPushMessage | StateInitMessage | StatePatchMessage | AuthRejectedMessage | PongMessage;
53
+ export declare class ConnectionLostError extends Error {
54
+ constructor();
55
+ }
56
+ export declare class AuthRejectedError extends Error {
57
+ constructor();
58
+ }
59
+ export declare class RpcError extends Error {
60
+ readonly serverMessage: string;
61
+ constructor(serverMessage: string);
62
+ }
63
+ export declare class TimeoutError extends Error {
64
+ constructor();
65
+ }
66
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/transport/protocol.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,KAAK,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;CACX;AAGD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,KAAK,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAA;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,eAAe,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG,kBAAkB,GAAG,WAAW,CAAA;AAErF,MAAM,MAAM,qBAAqB,GAC7B,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,WAAW,CAAA;AAEf,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;;CAK3C;AAED,qBAAa,QAAS,SAAQ,KAAK;aACL,aAAa,EAAE,MAAM;gBAArB,aAAa,EAAE,MAAM;CAIlD;AAED,qBAAa,YAAa,SAAQ,KAAK;;CAKtC"}
@@ -0,0 +1,27 @@
1
+ export class ConnectionLostError extends Error {
2
+ constructor() {
3
+ super('Connection lost');
4
+ this.name = 'ConnectionLostError';
5
+ }
6
+ }
7
+ export class AuthRejectedError extends Error {
8
+ constructor() {
9
+ super('Authentication rejected by server');
10
+ this.name = 'AuthRejectedError';
11
+ }
12
+ }
13
+ export class RpcError extends Error {
14
+ serverMessage;
15
+ constructor(serverMessage) {
16
+ super(serverMessage);
17
+ this.serverMessage = serverMessage;
18
+ this.name = 'RpcError';
19
+ }
20
+ }
21
+ export class TimeoutError extends Error {
22
+ constructor() {
23
+ super('RPC call timed out');
24
+ this.name = 'TimeoutError';
25
+ }
26
+ }
27
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/transport/protocol.ts"],"names":[],"mappings":"AAyEA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C;QACE,KAAK,CAAC,mCAAmC,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IACjC,CAAC;CACF;AAED,MAAM,OAAO,QAAS,SAAQ,KAAK;IACL;IAA5B,YAA4B,aAAqB;QAC/C,KAAK,CAAC,aAAa,CAAC,CAAA;QADM,kBAAa,GAAb,aAAa,CAAQ;QAE/C,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;IACxB,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC;QACE,KAAK,CAAC,oBAAoB,CAAC,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ import { BaseServerLifecycle } from '../lifecycle/base-server.js';
2
+ import { BaseStore } from '../store/base-store.js';
3
+ interface StoreRegistration {
4
+ name: string;
5
+ instance: BaseStore;
6
+ }
7
+ interface CreateRpcServerOptions {
8
+ stores: StoreRegistration[];
9
+ systems: object[];
10
+ lifecycle: BaseServerLifecycle;
11
+ port: number;
12
+ keepaliveInterval?: number;
13
+ maxConcurrentRpc?: number;
14
+ }
15
+ export interface RpcServer {
16
+ close(): Promise<void>;
17
+ /** Resolves once the server socket is bound and ready to accept connections. */
18
+ ready: Promise<void>;
19
+ /** The port the server is listening on. Valid after `ready` resolves. */
20
+ port: number;
21
+ }
22
+ export declare function createRPCServer(options: CreateRpcServerOptions): RpcServer;
23
+ export {};
24
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/transport/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAiBlD,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,UAAU,sBAAsB;IAC9B,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,mBAAmB,CAAA;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,gFAAgF;IAChF,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CA8L1E"}
@@ -0,0 +1,191 @@
1
+ import { WebSocketServer, WebSocket } from 'ws';
2
+ import { getMethodRoles } from '../decorators/metadata.js';
3
+ const AUTH_TIMEOUT_MS = 10_000;
4
+ const KEEPALIVE_INTERVAL_MS = 30_000;
5
+ const MAX_CONCURRENT_RPC = 50;
6
+ export function createRPCServer(options) {
7
+ const { stores, systems, lifecycle, port, keepaliveInterval = KEEPALIVE_INTERVAL_MS, maxConcurrentRpc = MAX_CONCURRENT_RPC, } = options;
8
+ const wss = new WebSocketServer({ port });
9
+ let actualPort = port;
10
+ let resolveReady;
11
+ const ready = new Promise(resolve => { resolveReady = resolve; });
12
+ wss.once('listening', () => {
13
+ actualPort = wss.address().port;
14
+ resolveReady();
15
+ });
16
+ const keepaliveTimer = setInterval(() => {
17
+ for (const ws of wss.clients) {
18
+ const ext = ws;
19
+ if (ext._isAlive === false) {
20
+ ws.terminate();
21
+ continue;
22
+ }
23
+ ext._isAlive = false;
24
+ ws.ping();
25
+ }
26
+ }, keepaliveInterval);
27
+ const connections = new Map();
28
+ const methods = new Map();
29
+ for (const system of systems) {
30
+ const proto = Object.getPrototypeOf(system);
31
+ const className = proto.constructor.name;
32
+ const roles = getMethodRoles(proto);
33
+ for (const [methodName, role] of Object.entries(roles)) {
34
+ if (role === 'server') {
35
+ const key = `${className}.${methodName}`;
36
+ methods.set(key, (ctx, ...args) => system[methodName](ctx, ...args));
37
+ }
38
+ }
39
+ }
40
+ for (const { name, instance } of stores) {
41
+ instance._onReplication = (batch) => {
42
+ if (batch.globalSeq > 0) {
43
+ const msg = { type: 'state_patch', store: name, scope: 'global', seq: batch.globalSeq, patch: batch.global };
44
+ const raw = JSON.stringify(msg);
45
+ for (const ws of connections.values()) {
46
+ if (ws.readyState === WebSocket.OPEN)
47
+ ws.send(raw);
48
+ }
49
+ }
50
+ for (const [playerId, { seq, patch }] of batch.ownerByPlayer) {
51
+ const ws = connections.get(playerId);
52
+ if (ws?.readyState === WebSocket.OPEN) {
53
+ ws.send(JSON.stringify({ type: 'state_patch', store: name, scope: 'owner', seq, patch }));
54
+ }
55
+ }
56
+ };
57
+ }
58
+ wss.on('connection', (ws, req) => {
59
+ ;
60
+ ws._isAlive = true;
61
+ ws.on('pong', () => { ws._isAlive = true; });
62
+ ws.on('message', () => { ws._isAlive = true; });
63
+ const authTimeout = setTimeout(() => ws.close(), AUTH_TIMEOUT_MS);
64
+ ws.once('message', async (raw) => {
65
+ // Fix 1: declare playerId in outer scope so catch can clean up
66
+ let playerId = null;
67
+ try {
68
+ let firstMsg;
69
+ try {
70
+ firstMsg = JSON.parse(raw.toString());
71
+ }
72
+ catch {
73
+ ws.close();
74
+ return;
75
+ }
76
+ if (firstMsg.type !== 'auth') {
77
+ ws.close();
78
+ return;
79
+ }
80
+ const connectReq = {
81
+ headers: req.headers, // Fix 5: removed overly-restrictive cast
82
+ url: req.url ?? '/',
83
+ payload: firstMsg.payload,
84
+ };
85
+ playerId = await lifecycle.onConnect(connectReq);
86
+ clearTimeout(authTimeout);
87
+ if (playerId === null) {
88
+ ws.send(JSON.stringify({ type: 'auth_rejected' }));
89
+ ws.close();
90
+ return;
91
+ }
92
+ // Use a const-typed alias after the null-guard for use in closures
93
+ const pid = playerId;
94
+ connections.set(pid, ws);
95
+ ws.send(JSON.stringify({ type: 'connected', playerId: pid, storeCount: stores.length }));
96
+ for (const { name, instance } of stores) {
97
+ const snapshot = instance.getSnapshot(pid);
98
+ ws.send(JSON.stringify({ type: 'state_init', store: name, snapshot }));
99
+ }
100
+ const ctx = {
101
+ playerId: pid,
102
+ get players() { return [...connections.keys()]; },
103
+ sendToClient(targetId, method, ...args) {
104
+ const target = connections.get(targetId);
105
+ if (target?.readyState === WebSocket.OPEN) {
106
+ target.send(JSON.stringify({ type: 'rpc', method, args }));
107
+ }
108
+ },
109
+ };
110
+ // Fix 2: register RPC and close handlers BEFORE awaiting onPlayerJoined
111
+ let inFlight = 0;
112
+ let joined = false;
113
+ ws.on('message', async (raw) => {
114
+ let msg;
115
+ try {
116
+ msg = JSON.parse(raw.toString());
117
+ }
118
+ catch {
119
+ return;
120
+ }
121
+ if (msg.type === 'ping') {
122
+ ws.send(JSON.stringify({ type: 'pong', id: msg.id }));
123
+ return;
124
+ }
125
+ if (msg.type !== 'rpc')
126
+ return;
127
+ if (inFlight >= maxConcurrentRpc) {
128
+ ws.send(JSON.stringify({ type: 'rpc_result', id: msg.id, error: 'Too many concurrent requests' }));
129
+ return;
130
+ }
131
+ const handler = methods.get(msg.method);
132
+ if (!handler) {
133
+ ws.send(JSON.stringify({ type: 'rpc_result', id: msg.id, error: `Unknown method: ${msg.method}` }));
134
+ return;
135
+ }
136
+ inFlight++;
137
+ try {
138
+ const result = await handler(ctx, ...msg.args);
139
+ ws.send(JSON.stringify({ type: 'rpc_result', id: msg.id, result }));
140
+ }
141
+ catch (err) {
142
+ ws.send(JSON.stringify({
143
+ type: 'rpc_result',
144
+ id: msg.id,
145
+ error: err instanceof Error ? err.message : String(err),
146
+ }));
147
+ }
148
+ finally {
149
+ inFlight--;
150
+ }
151
+ });
152
+ ws.on('close', async () => {
153
+ if (!joined)
154
+ return; // player never successfully joined
155
+ // Fix 3: guard against reconnect overwriting the map entry
156
+ if (connections.get(pid) === ws)
157
+ connections.delete(pid);
158
+ await lifecycle.onPlayerLeft(ctx);
159
+ });
160
+ await lifecycle.onPlayerJoined(ctx);
161
+ joined = true;
162
+ }
163
+ catch (err) {
164
+ // Fix 1: on any error (e.g. onPlayerJoined throw), clean up connection and close
165
+ if (playerId !== null)
166
+ connections.delete(playerId);
167
+ ws.close();
168
+ }
169
+ });
170
+ });
171
+ let closed = false;
172
+ return {
173
+ ready,
174
+ get port() { return actualPort; },
175
+ close: () => {
176
+ if (closed)
177
+ return Promise.resolve();
178
+ closed = true;
179
+ clearInterval(keepaliveTimer);
180
+ // Fix 4: null out store replication callbacks
181
+ for (const { instance } of stores) {
182
+ instance._onReplication = undefined;
183
+ }
184
+ for (const ws of wss.clients) {
185
+ ws.terminate();
186
+ }
187
+ return new Promise((resolve, reject) => wss.close(err => err ? reject(err) : resolve()));
188
+ },
189
+ };
190
+ }
191
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/transport/server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@replicast/core",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript RPC and state-replication framework for multiplayer games",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": ["dist"],
10
+ "scripts": {
11
+ "build": "tsc -p tsconfig.build.json",
12
+ "test": "vitest run"
13
+ },
14
+ "dependencies": {
15
+ "reflect-metadata": "^0.2.0",
16
+ "uuid": "^10.0.0",
17
+ "ws": "^8.18.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/uuid": "^10.0.0",
21
+ "@types/ws": "^8.5.0",
22
+ "vitest": "^1.6.0"
23
+ }
24
+ }