@react-remote-state/client 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -54,11 +54,26 @@ function isHost(playerId, game) {
54
54
  let player = getPlayer(playerId, game);
55
55
  return player == null ? void 0 : player.host;
56
56
  }
57
+ function wrapReducer(reducer) {
58
+ return (game, internalAction) => {
59
+ switch (internalAction.type) {
60
+ case 1 /* Update */:
61
+ return internalAction.game;
62
+ case 0 /* Reduce */:
63
+ if (!!game) {
64
+ internalAction.client.emit("update", {
65
+ game: reducer(game, internalAction.action, internalAction.playerId)
66
+ });
67
+ }
68
+ return game;
69
+ }
70
+ };
71
+ }
57
72
  function useRemoteReducer(uri, reducer, gameId) {
58
73
  let [meta, setMeta] = (0, import_react.useState)({
59
74
  isHostReady: false
60
75
  });
61
- let [game, setGame] = (0, import_react.useState)();
76
+ let [game, internalDispatch] = (0, import_react.useReducer)(wrapReducer(reducer), void 0);
62
77
  let dispatch = (action) => {
63
78
  if (!!meta.client && !!game) {
64
79
  meta.client.emit("notify", { gameId: game.id, action });
@@ -66,7 +81,7 @@ function useRemoteReducer(uri, reducer, gameId) {
66
81
  };
67
82
  (0, import_react.useEffect)(() => {
68
83
  if (!meta.client) {
69
- meta.client = (0, import_socket.connect)(uri);
84
+ meta.client = (0, import_socket.connect)(uri, { transports: ["websocket"] });
70
85
  meta.client.on("error", console.error);
71
86
  meta.client.on("connect", () => {
72
87
  var _a, _b;
@@ -79,9 +94,10 @@ function useRemoteReducer(uri, reducer, gameId) {
79
94
  meta.client.on("assign", (assign) => {
80
95
  setMeta(__spreadProps(__spreadValues({}, meta), { localPlayerId: assign.playerId }));
81
96
  });
82
- meta.client.on("update", (update) => {
83
- setGame(update.game);
84
- });
97
+ meta.client.on(
98
+ "update",
99
+ (update) => internalDispatch({ type: 1 /* Update */, game: update.game })
100
+ );
85
101
  } else if (isHost(meta.localPlayerId, game) && !meta.isHostReady) {
86
102
  meta.client.on("join", (join) => {
87
103
  var _a;
@@ -91,10 +107,12 @@ function useRemoteReducer(uri, reducer, gameId) {
91
107
  });
92
108
  });
93
109
  meta.client.on("notify", (notify) => {
94
- var _a;
95
- if (!!game) {
96
- (_a = meta.client) == null ? void 0 : _a.emit("update", {
97
- game: reducer(game, notify.action, notify.playerId)
110
+ if (!!game && !!meta.client) {
111
+ internalDispatch({
112
+ type: 0 /* Reduce */,
113
+ client: meta.client,
114
+ playerId: notify.playerId,
115
+ action: notify.action
98
116
  });
99
117
  }
100
118
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Game } from \"@react-remote-state/types\";\nimport { useEffect, useState } from \"react\";\nimport { connect, Socket as Client } from \"socket.io-client\";\n\ntype Meta = {\n client?: Client;\n isHostReady: boolean;\n localPlayerId?: string;\n};\n\nexport function getPlayer<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n if (!game || !playerId) {\n return undefined;\n }\n\n return game.players.find((player) => player.id == playerId);\n}\n\nexport function isHost<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n let player = getPlayer(playerId, game);\n\n return player?.host;\n}\n\ntype Reducer<GameCustom, PlayerCustom, Action> = (\n game: Game<GameCustom, PlayerCustom>,\n action: Action,\n playerId: string\n) => Game<GameCustom, PlayerCustom>;\n\nexport function useRemoteReducer<GameCustom, PlayerCustom, Action>(\n uri: string,\n reducer: Reducer<GameCustom, PlayerCustom, Action>,\n gameId?: string\n): [\n Game<GameCustom, PlayerCustom> | undefined,\n string | undefined,\n (action: Action) => void\n] {\n let [meta, setMeta] = useState<Meta>({\n isHostReady: false,\n });\n\n let [game, setGame] = useState<Game<GameCustom, PlayerCustom>>();\n\n let dispatch = (action: Action) => {\n if (!!meta.client && !!game) {\n meta.client.emit(\"notify\", { gameId: game.id, action });\n }\n };\n\n useEffect(() => {\n if (!meta.client) {\n meta.client = connect(uri);\n meta.client.on(\"error\", console.error);\n meta.client.on(\"connect\", () => {\n if (gameId == undefined) {\n meta.client?.emit(\"create\");\n } else {\n meta.client?.emit(\"join\", { gameId });\n }\n });\n\n meta.client.on(\"assign\", (assign) => {\n setMeta({ ...meta, localPlayerId: assign.playerId });\n });\n\n meta.client.on(\"update\", (update) => {\n setGame(update.game);\n });\n } else if (isHost(meta.localPlayerId, game) && !meta.isHostReady) {\n meta.client.on(\"join\", (join) => {\n meta.client?.emit(\"accept\", {\n gameId: game?.id,\n playerId: join.playerId,\n });\n });\n\n meta.client.on(\"notify\", (notify) => {\n if (!!game) {\n meta.client?.emit(\"update\", {\n game: reducer(game, notify.action, notify.playerId),\n });\n }\n });\n\n setMeta({ ...meta, isHostReady: true });\n }\n });\n\n return [game, meta.localPlayerId, dispatch];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAoC;AACpC,oBAA0C;AAQnC,SAAS,UACd,UACA,MACA;AACA,MAAI,CAAC,QAAQ,CAAC,UAAU;AACtB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,KAAK,CAAC,WAAW,OAAO,MAAM,QAAQ;AAC5D;AAEO,SAAS,OACd,UACA,MACA;AACA,MAAI,SAAS,UAAU,UAAU,IAAI;AAErC,SAAO,iCAAQ;AACjB;AAQO,SAAS,iBACd,KACA,SACA,QAKA;AACA,MAAI,CAAC,MAAM,OAAO,QAAI,uBAAe;AAAA,IACnC,aAAa;AAAA,EACf,CAAC;AAED,MAAI,CAAC,MAAM,OAAO,QAAI,uBAAyC;AAE/D,MAAI,WAAW,CAAC,WAAmB;AACjC,QAAI,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM;AAC3B,WAAK,OAAO,KAAK,UAAU,EAAE,QAAQ,KAAK,IAAI,OAAO,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,8BAAU,MAAM;AACd,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,aAAS,uBAAQ,GAAG;AACzB,WAAK,OAAO,GAAG,SAAS,QAAQ,KAAK;AACrC,WAAK,OAAO,GAAG,WAAW,MAAM;AA7DtC;AA8DQ,YAAI,UAAU,QAAW;AACvB,qBAAK,WAAL,mBAAa,KAAK;AAAA,QACpB,OAAO;AACL,qBAAK,WAAL,mBAAa,KAAK,QAAQ,EAAE,OAAO;AAAA,QACrC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,gBAAQ,iCAAK,OAAL,EAAW,eAAe,OAAO,SAAS,EAAC;AAAA,MACrD,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,gBAAQ,OAAO,IAAI;AAAA,MACrB,CAAC;AAAA,IACH,WAAW,OAAO,KAAK,eAAe,IAAI,KAAK,CAAC,KAAK,aAAa;AAChE,WAAK,OAAO,GAAG,QAAQ,CAAC,SAAS;AA7EvC;AA8EQ,mBAAK,WAAL,mBAAa,KAAK,UAAU;AAAA,UAC1B,QAAQ,6BAAM;AAAA,UACd,UAAU,KAAK;AAAA,QACjB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AApF3C;AAqFQ,YAAI,CAAC,CAAC,MAAM;AACV,qBAAK,WAAL,mBAAa,KAAK,UAAU;AAAA,YAC1B,MAAM,QAAQ,MAAM,OAAO,QAAQ,OAAO,QAAQ;AAAA,UACpD;AAAA,QACF;AAAA,MACF,CAAC;AAED,cAAQ,iCAAK,OAAL,EAAW,aAAa,KAAK,EAAC;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO,CAAC,MAAM,KAAK,eAAe,QAAQ;AAC5C;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Game } from \"@react-remote-state/types\";\nimport { useEffect, useReducer, useState } from \"react\";\nimport { connect, Socket as Client } from \"socket.io-client\";\n\ntype Meta = {\n client?: Client;\n isHostReady: boolean;\n localPlayerId?: string;\n};\n\nexport function getPlayer<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n if (!game || !playerId) {\n return undefined;\n }\n\n return game.players.find((player) => player.id == playerId);\n}\n\nexport function isHost<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n let player = getPlayer(playerId, game);\n\n return player?.host;\n}\n\ntype Reducer<GameCustom, PlayerCustom, Action> = (\n game: Game<GameCustom, PlayerCustom>,\n action: Action,\n playerId: string\n) => Game<GameCustom, PlayerCustom>;\n\nenum InternalActionType {\n Reduce,\n Update,\n}\n\ntype InternalReduceAction<Action> = {\n type: InternalActionType.Reduce;\n client: Client;\n playerId: string;\n action: Action;\n};\n\ntype InternalUpdateAction<GameCustom, PlayerCustom> = {\n type: InternalActionType.Update;\n game: Game<GameCustom, PlayerCustom>;\n};\n\ntype InternalAction<GameCustom, PlayerCustom, Action> =\n | InternalReduceAction<Action>\n | InternalUpdateAction<GameCustom, PlayerCustom>;\n\nfunction wrapReducer<GameCustom, PlayerCustom, Action>(\n reducer: Reducer<GameCustom, PlayerCustom, Action>\n) {\n return (\n game: Game<GameCustom, PlayerCustom> | undefined,\n internalAction: InternalAction<GameCustom, PlayerCustom, Action>\n ) => {\n switch (internalAction.type) {\n case InternalActionType.Update:\n return internalAction.game;\n case InternalActionType.Reduce:\n if (!!game) {\n internalAction.client.emit(\"update\", {\n game: reducer(game, internalAction.action, internalAction.playerId),\n });\n }\n\n return game;\n }\n };\n}\n\nexport function useRemoteReducer<GameCustom, PlayerCustom, Action>(\n uri: string,\n reducer: Reducer<GameCustom, PlayerCustom, Action>,\n gameId?: string\n): [\n Game<GameCustom, PlayerCustom> | undefined,\n string | undefined,\n (action: Action) => void\n] {\n let [meta, setMeta] = useState<Meta>({\n isHostReady: false,\n });\n\n let [game, internalDispatch] = useReducer(wrapReducer(reducer), undefined);\n\n let dispatch = (action: Action) => {\n if (!!meta.client && !!game) {\n meta.client.emit(\"notify\", { gameId: game.id, action });\n }\n };\n\n useEffect(() => {\n if (!meta.client) {\n meta.client = connect(uri, { transports: [\"websocket\"] });\n meta.client.on(\"error\", console.error);\n meta.client.on(\"connect\", () => {\n if (gameId == undefined) {\n meta.client?.emit(\"create\");\n } else {\n meta.client?.emit(\"join\", { gameId });\n }\n });\n\n meta.client.on(\"assign\", (assign) => {\n setMeta({ ...meta, localPlayerId: assign.playerId });\n });\n\n meta.client.on(\"update\", (update) =>\n internalDispatch({ type: InternalActionType.Update, game: update.game })\n );\n } else if (isHost(meta.localPlayerId, game) && !meta.isHostReady) {\n meta.client.on(\"join\", (join) => {\n meta.client?.emit(\"accept\", {\n gameId: game?.id,\n playerId: join.playerId,\n });\n });\n\n meta.client.on(\"notify\", (notify) => {\n if (!!game && !!meta.client) {\n internalDispatch({\n type: InternalActionType.Reduce,\n client: meta.client,\n playerId: notify.playerId,\n action: notify.action,\n });\n }\n });\n\n setMeta({ ...meta, isHostReady: true });\n }\n });\n\n return [game, meta.localPlayerId, dispatch];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAAgD;AAChD,oBAA0C;AAQnC,SAAS,UACd,UACA,MACA;AACA,MAAI,CAAC,QAAQ,CAAC,UAAU;AACtB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,KAAK,CAAC,WAAW,OAAO,MAAM,QAAQ;AAC5D;AAEO,SAAS,OACd,UACA,MACA;AACA,MAAI,SAAS,UAAU,UAAU,IAAI;AAErC,SAAO,iCAAQ;AACjB;AA6BA,SAAS,YACP,SACA;AACA,SAAO,CACL,MACA,mBACG;AACH,YAAQ,eAAe,MAAM;AAAA,MAC3B,KAAK;AACH,eAAO,eAAe;AAAA,MACxB,KAAK;AACH,YAAI,CAAC,CAAC,MAAM;AACV,yBAAe,OAAO,KAAK,UAAU;AAAA,YACnC,MAAM,QAAQ,MAAM,eAAe,QAAQ,eAAe,QAAQ;AAAA,UACpE,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,IACX;AAAA,EACF;AACF;AAEO,SAAS,iBACd,KACA,SACA,QAKA;AACA,MAAI,CAAC,MAAM,OAAO,QAAI,uBAAe;AAAA,IACnC,aAAa;AAAA,EACf,CAAC;AAED,MAAI,CAAC,MAAM,gBAAgB,QAAI,yBAAW,YAAY,OAAO,GAAG,MAAS;AAEzE,MAAI,WAAW,CAAC,WAAmB;AACjC,QAAI,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM;AAC3B,WAAK,OAAO,KAAK,UAAU,EAAE,QAAQ,KAAK,IAAI,OAAO,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,8BAAU,MAAM;AACd,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,aAAS,uBAAQ,KAAK,EAAE,YAAY,CAAC,WAAW,EAAE,CAAC;AACxD,WAAK,OAAO,GAAG,SAAS,QAAQ,KAAK;AACrC,WAAK,OAAO,GAAG,WAAW,MAAM;AAxGtC;AAyGQ,YAAI,UAAU,QAAW;AACvB,qBAAK,WAAL,mBAAa,KAAK;AAAA,QACpB,OAAO;AACL,qBAAK,WAAL,mBAAa,KAAK,QAAQ,EAAE,OAAO;AAAA,QACrC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,gBAAQ,iCAAK,OAAL,EAAW,eAAe,OAAO,SAAS,EAAC;AAAA,MACrD,CAAC;AAED,WAAK,OAAO;AAAA,QAAG;AAAA,QAAU,CAAC,WACxB,iBAAiB,EAAE,MAAM,gBAA2B,MAAM,OAAO,KAAK,CAAC;AAAA,MACzE;AAAA,IACF,WAAW,OAAO,KAAK,eAAe,IAAI,KAAK,CAAC,KAAK,aAAa;AAChE,WAAK,OAAO,GAAG,QAAQ,CAAC,SAAS;AAxHvC;AAyHQ,mBAAK,WAAL,mBAAa,KAAK,UAAU;AAAA,UAC1B,QAAQ,6BAAM;AAAA,UACd,UAAU,KAAK;AAAA,QACjB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,YAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,QAAQ;AAC3B,2BAAiB;AAAA,YACf,MAAM;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,UAAU,OAAO;AAAA,YACjB,QAAQ,OAAO;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,cAAQ,iCAAK,OAAL,EAAW,aAAa,KAAK,EAAC;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO,CAAC,MAAM,KAAK,eAAe,QAAQ;AAC5C;","names":[]}
package/dist/index.mjs CHANGED
@@ -19,7 +19,7 @@ var __spreadValues = (a, b) => {
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
 
21
21
  // src/index.ts
22
- import { useEffect, useState } from "react";
22
+ import { useEffect, useReducer, useState } from "react";
23
23
  import { connect } from "socket.io-client";
24
24
  function getPlayer(playerId, game) {
25
25
  if (!game || !playerId) {
@@ -31,11 +31,26 @@ function isHost(playerId, game) {
31
31
  let player = getPlayer(playerId, game);
32
32
  return player == null ? void 0 : player.host;
33
33
  }
34
+ function wrapReducer(reducer) {
35
+ return (game, internalAction) => {
36
+ switch (internalAction.type) {
37
+ case 1 /* Update */:
38
+ return internalAction.game;
39
+ case 0 /* Reduce */:
40
+ if (!!game) {
41
+ internalAction.client.emit("update", {
42
+ game: reducer(game, internalAction.action, internalAction.playerId)
43
+ });
44
+ }
45
+ return game;
46
+ }
47
+ };
48
+ }
34
49
  function useRemoteReducer(uri, reducer, gameId) {
35
50
  let [meta, setMeta] = useState({
36
51
  isHostReady: false
37
52
  });
38
- let [game, setGame] = useState();
53
+ let [game, internalDispatch] = useReducer(wrapReducer(reducer), void 0);
39
54
  let dispatch = (action) => {
40
55
  if (!!meta.client && !!game) {
41
56
  meta.client.emit("notify", { gameId: game.id, action });
@@ -43,7 +58,7 @@ function useRemoteReducer(uri, reducer, gameId) {
43
58
  };
44
59
  useEffect(() => {
45
60
  if (!meta.client) {
46
- meta.client = connect(uri);
61
+ meta.client = connect(uri, { transports: ["websocket"] });
47
62
  meta.client.on("error", console.error);
48
63
  meta.client.on("connect", () => {
49
64
  var _a, _b;
@@ -56,9 +71,10 @@ function useRemoteReducer(uri, reducer, gameId) {
56
71
  meta.client.on("assign", (assign) => {
57
72
  setMeta(__spreadProps(__spreadValues({}, meta), { localPlayerId: assign.playerId }));
58
73
  });
59
- meta.client.on("update", (update) => {
60
- setGame(update.game);
61
- });
74
+ meta.client.on(
75
+ "update",
76
+ (update) => internalDispatch({ type: 1 /* Update */, game: update.game })
77
+ );
62
78
  } else if (isHost(meta.localPlayerId, game) && !meta.isHostReady) {
63
79
  meta.client.on("join", (join) => {
64
80
  var _a;
@@ -68,10 +84,12 @@ function useRemoteReducer(uri, reducer, gameId) {
68
84
  });
69
85
  });
70
86
  meta.client.on("notify", (notify) => {
71
- var _a;
72
- if (!!game) {
73
- (_a = meta.client) == null ? void 0 : _a.emit("update", {
74
- game: reducer(game, notify.action, notify.playerId)
87
+ if (!!game && !!meta.client) {
88
+ internalDispatch({
89
+ type: 0 /* Reduce */,
90
+ client: meta.client,
91
+ playerId: notify.playerId,
92
+ action: notify.action
75
93
  });
76
94
  }
77
95
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Game } from \"@react-remote-state/types\";\nimport { useEffect, useState } from \"react\";\nimport { connect, Socket as Client } from \"socket.io-client\";\n\ntype Meta = {\n client?: Client;\n isHostReady: boolean;\n localPlayerId?: string;\n};\n\nexport function getPlayer<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n if (!game || !playerId) {\n return undefined;\n }\n\n return game.players.find((player) => player.id == playerId);\n}\n\nexport function isHost<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n let player = getPlayer(playerId, game);\n\n return player?.host;\n}\n\ntype Reducer<GameCustom, PlayerCustom, Action> = (\n game: Game<GameCustom, PlayerCustom>,\n action: Action,\n playerId: string\n) => Game<GameCustom, PlayerCustom>;\n\nexport function useRemoteReducer<GameCustom, PlayerCustom, Action>(\n uri: string,\n reducer: Reducer<GameCustom, PlayerCustom, Action>,\n gameId?: string\n): [\n Game<GameCustom, PlayerCustom> | undefined,\n string | undefined,\n (action: Action) => void\n] {\n let [meta, setMeta] = useState<Meta>({\n isHostReady: false,\n });\n\n let [game, setGame] = useState<Game<GameCustom, PlayerCustom>>();\n\n let dispatch = (action: Action) => {\n if (!!meta.client && !!game) {\n meta.client.emit(\"notify\", { gameId: game.id, action });\n }\n };\n\n useEffect(() => {\n if (!meta.client) {\n meta.client = connect(uri);\n meta.client.on(\"error\", console.error);\n meta.client.on(\"connect\", () => {\n if (gameId == undefined) {\n meta.client?.emit(\"create\");\n } else {\n meta.client?.emit(\"join\", { gameId });\n }\n });\n\n meta.client.on(\"assign\", (assign) => {\n setMeta({ ...meta, localPlayerId: assign.playerId });\n });\n\n meta.client.on(\"update\", (update) => {\n setGame(update.game);\n });\n } else if (isHost(meta.localPlayerId, game) && !meta.isHostReady) {\n meta.client.on(\"join\", (join) => {\n meta.client?.emit(\"accept\", {\n gameId: game?.id,\n playerId: join.playerId,\n });\n });\n\n meta.client.on(\"notify\", (notify) => {\n if (!!game) {\n meta.client?.emit(\"update\", {\n game: reducer(game, notify.action, notify.playerId),\n });\n }\n });\n\n setMeta({ ...meta, isHostReady: true });\n }\n });\n\n return [game, meta.localPlayerId, dispatch];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AACA,SAAS,WAAW,gBAAgB;AACpC,SAAS,eAAiC;AAQnC,SAAS,UACd,UACA,MACA;AACA,MAAI,CAAC,QAAQ,CAAC,UAAU;AACtB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,KAAK,CAAC,WAAW,OAAO,MAAM,QAAQ;AAC5D;AAEO,SAAS,OACd,UACA,MACA;AACA,MAAI,SAAS,UAAU,UAAU,IAAI;AAErC,SAAO,iCAAQ;AACjB;AAQO,SAAS,iBACd,KACA,SACA,QAKA;AACA,MAAI,CAAC,MAAM,OAAO,IAAI,SAAe;AAAA,IACnC,aAAa;AAAA,EACf,CAAC;AAED,MAAI,CAAC,MAAM,OAAO,IAAI,SAAyC;AAE/D,MAAI,WAAW,CAAC,WAAmB;AACjC,QAAI,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM;AAC3B,WAAK,OAAO,KAAK,UAAU,EAAE,QAAQ,KAAK,IAAI,OAAO,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS,QAAQ,GAAG;AACzB,WAAK,OAAO,GAAG,SAAS,QAAQ,KAAK;AACrC,WAAK,OAAO,GAAG,WAAW,MAAM;AA7DtC;AA8DQ,YAAI,UAAU,QAAW;AACvB,qBAAK,WAAL,mBAAa,KAAK;AAAA,QACpB,OAAO;AACL,qBAAK,WAAL,mBAAa,KAAK,QAAQ,EAAE,OAAO;AAAA,QACrC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,gBAAQ,iCAAK,OAAL,EAAW,eAAe,OAAO,SAAS,EAAC;AAAA,MACrD,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,gBAAQ,OAAO,IAAI;AAAA,MACrB,CAAC;AAAA,IACH,WAAW,OAAO,KAAK,eAAe,IAAI,KAAK,CAAC,KAAK,aAAa;AAChE,WAAK,OAAO,GAAG,QAAQ,CAAC,SAAS;AA7EvC;AA8EQ,mBAAK,WAAL,mBAAa,KAAK,UAAU;AAAA,UAC1B,QAAQ,6BAAM;AAAA,UACd,UAAU,KAAK;AAAA,QACjB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AApF3C;AAqFQ,YAAI,CAAC,CAAC,MAAM;AACV,qBAAK,WAAL,mBAAa,KAAK,UAAU;AAAA,YAC1B,MAAM,QAAQ,MAAM,OAAO,QAAQ,OAAO,QAAQ;AAAA,UACpD;AAAA,QACF;AAAA,MACF,CAAC;AAED,cAAQ,iCAAK,OAAL,EAAW,aAAa,KAAK,EAAC;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO,CAAC,MAAM,KAAK,eAAe,QAAQ;AAC5C;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Game } from \"@react-remote-state/types\";\nimport { useEffect, useReducer, useState } from \"react\";\nimport { connect, Socket as Client } from \"socket.io-client\";\n\ntype Meta = {\n client?: Client;\n isHostReady: boolean;\n localPlayerId?: string;\n};\n\nexport function getPlayer<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n if (!game || !playerId) {\n return undefined;\n }\n\n return game.players.find((player) => player.id == playerId);\n}\n\nexport function isHost<GameCustom, PlayerCustom>(\n playerId?: string,\n game?: Game<GameCustom, PlayerCustom>\n) {\n let player = getPlayer(playerId, game);\n\n return player?.host;\n}\n\ntype Reducer<GameCustom, PlayerCustom, Action> = (\n game: Game<GameCustom, PlayerCustom>,\n action: Action,\n playerId: string\n) => Game<GameCustom, PlayerCustom>;\n\nenum InternalActionType {\n Reduce,\n Update,\n}\n\ntype InternalReduceAction<Action> = {\n type: InternalActionType.Reduce;\n client: Client;\n playerId: string;\n action: Action;\n};\n\ntype InternalUpdateAction<GameCustom, PlayerCustom> = {\n type: InternalActionType.Update;\n game: Game<GameCustom, PlayerCustom>;\n};\n\ntype InternalAction<GameCustom, PlayerCustom, Action> =\n | InternalReduceAction<Action>\n | InternalUpdateAction<GameCustom, PlayerCustom>;\n\nfunction wrapReducer<GameCustom, PlayerCustom, Action>(\n reducer: Reducer<GameCustom, PlayerCustom, Action>\n) {\n return (\n game: Game<GameCustom, PlayerCustom> | undefined,\n internalAction: InternalAction<GameCustom, PlayerCustom, Action>\n ) => {\n switch (internalAction.type) {\n case InternalActionType.Update:\n return internalAction.game;\n case InternalActionType.Reduce:\n if (!!game) {\n internalAction.client.emit(\"update\", {\n game: reducer(game, internalAction.action, internalAction.playerId),\n });\n }\n\n return game;\n }\n };\n}\n\nexport function useRemoteReducer<GameCustom, PlayerCustom, Action>(\n uri: string,\n reducer: Reducer<GameCustom, PlayerCustom, Action>,\n gameId?: string\n): [\n Game<GameCustom, PlayerCustom> | undefined,\n string | undefined,\n (action: Action) => void\n] {\n let [meta, setMeta] = useState<Meta>({\n isHostReady: false,\n });\n\n let [game, internalDispatch] = useReducer(wrapReducer(reducer), undefined);\n\n let dispatch = (action: Action) => {\n if (!!meta.client && !!game) {\n meta.client.emit(\"notify\", { gameId: game.id, action });\n }\n };\n\n useEffect(() => {\n if (!meta.client) {\n meta.client = connect(uri, { transports: [\"websocket\"] });\n meta.client.on(\"error\", console.error);\n meta.client.on(\"connect\", () => {\n if (gameId == undefined) {\n meta.client?.emit(\"create\");\n } else {\n meta.client?.emit(\"join\", { gameId });\n }\n });\n\n meta.client.on(\"assign\", (assign) => {\n setMeta({ ...meta, localPlayerId: assign.playerId });\n });\n\n meta.client.on(\"update\", (update) =>\n internalDispatch({ type: InternalActionType.Update, game: update.game })\n );\n } else if (isHost(meta.localPlayerId, game) && !meta.isHostReady) {\n meta.client.on(\"join\", (join) => {\n meta.client?.emit(\"accept\", {\n gameId: game?.id,\n playerId: join.playerId,\n });\n });\n\n meta.client.on(\"notify\", (notify) => {\n if (!!game && !!meta.client) {\n internalDispatch({\n type: InternalActionType.Reduce,\n client: meta.client,\n playerId: notify.playerId,\n action: notify.action,\n });\n }\n });\n\n setMeta({ ...meta, isHostReady: true });\n }\n });\n\n return [game, meta.localPlayerId, dispatch];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AACA,SAAS,WAAW,YAAY,gBAAgB;AAChD,SAAS,eAAiC;AAQnC,SAAS,UACd,UACA,MACA;AACA,MAAI,CAAC,QAAQ,CAAC,UAAU;AACtB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,KAAK,CAAC,WAAW,OAAO,MAAM,QAAQ;AAC5D;AAEO,SAAS,OACd,UACA,MACA;AACA,MAAI,SAAS,UAAU,UAAU,IAAI;AAErC,SAAO,iCAAQ;AACjB;AA6BA,SAAS,YACP,SACA;AACA,SAAO,CACL,MACA,mBACG;AACH,YAAQ,eAAe,MAAM;AAAA,MAC3B,KAAK;AACH,eAAO,eAAe;AAAA,MACxB,KAAK;AACH,YAAI,CAAC,CAAC,MAAM;AACV,yBAAe,OAAO,KAAK,UAAU;AAAA,YACnC,MAAM,QAAQ,MAAM,eAAe,QAAQ,eAAe,QAAQ;AAAA,UACpE,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,IACX;AAAA,EACF;AACF;AAEO,SAAS,iBACd,KACA,SACA,QAKA;AACA,MAAI,CAAC,MAAM,OAAO,IAAI,SAAe;AAAA,IACnC,aAAa;AAAA,EACf,CAAC;AAED,MAAI,CAAC,MAAM,gBAAgB,IAAI,WAAW,YAAY,OAAO,GAAG,MAAS;AAEzE,MAAI,WAAW,CAAC,WAAmB;AACjC,QAAI,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM;AAC3B,WAAK,OAAO,KAAK,UAAU,EAAE,QAAQ,KAAK,IAAI,OAAO,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS,QAAQ,KAAK,EAAE,YAAY,CAAC,WAAW,EAAE,CAAC;AACxD,WAAK,OAAO,GAAG,SAAS,QAAQ,KAAK;AACrC,WAAK,OAAO,GAAG,WAAW,MAAM;AAxGtC;AAyGQ,YAAI,UAAU,QAAW;AACvB,qBAAK,WAAL,mBAAa,KAAK;AAAA,QACpB,OAAO;AACL,qBAAK,WAAL,mBAAa,KAAK,QAAQ,EAAE,OAAO;AAAA,QACrC;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,gBAAQ,iCAAK,OAAL,EAAW,eAAe,OAAO,SAAS,EAAC;AAAA,MACrD,CAAC;AAED,WAAK,OAAO;AAAA,QAAG;AAAA,QAAU,CAAC,WACxB,iBAAiB,EAAE,MAAM,gBAA2B,MAAM,OAAO,KAAK,CAAC;AAAA,MACzE;AAAA,IACF,WAAW,OAAO,KAAK,eAAe,IAAI,KAAK,CAAC,KAAK,aAAa;AAChE,WAAK,OAAO,GAAG,QAAQ,CAAC,SAAS;AAxHvC;AAyHQ,mBAAK,WAAL,mBAAa,KAAK,UAAU;AAAA,UAC1B,QAAQ,6BAAM;AAAA,UACd,UAAU,KAAK;AAAA,QACjB;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,UAAU,CAAC,WAAW;AACnC,YAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,QAAQ;AAC3B,2BAAiB;AAAA,YACf,MAAM;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,UAAU,OAAO;AAAA,YACjB,QAAQ,OAAO;AAAA,UACjB,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,cAAQ,iCAAK,OAAL,EAAW,aAAa,KAAK,EAAC;AAAA,IACxC;AAAA,EACF,CAAC;AAED,SAAO,CAAC,MAAM,KAAK,eAAe,QAAQ;AAC5C;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-remote-state/client",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Client for React Remote State applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",