Full Code of mfrachet/use-socketio for AI

master 9c3d1d11984a cached
55 files
38.3 KB
11.8k tokens
3 symbols
1 requests
Download .txt
Repository: mfrachet/use-socketio
Branch: master
Commit: 9c3d1d11984a
Files: 55
Total size: 38.3 KB

Directory structure:
gitextract_ge2hlk0j/

├── .github/
│   └── workflows/
│       └── test_pr.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── cypress/
│   ├── fixtures/
│   │   └── example.json
│   ├── integration/
│   │   ├── socketio.spec.js
│   │   ├── sse.spec.js
│   │   └── websocket.spec.js
│   ├── plugins/
│   │   └── index.js
│   └── support/
│       ├── commands.js
│       └── index.js
├── cypress.json
├── example/
│   ├── App.js
│   ├── index.html
│   ├── index.js
│   ├── server-helpers.js
│   ├── server.js
│   ├── socketio/
│   │   ├── SocketIo.js
│   │   ├── constants.js
│   │   └── socketio-server.js
│   ├── sse/
│   │   ├── SSE.js
│   │   ├── constants.js
│   │   └── sse-server.js
│   └── websocket/
│       ├── Websocket.js
│       ├── constants.js
│       └── websocket-server.js
├── lerna.json
├── package.json
└── packages/
    ├── use-server-sent-events/
    │   ├── .npmignore
    │   ├── README.md
    │   ├── package.json
    │   ├── src/
    │   │   ├── context.ts
    │   │   ├── hooks.ts
    │   │   ├── index.tsx
    │   │   └── provider.tsx
    │   ├── tsconfig.json
    │   └── tslint.json
    ├── use-socketio/
    │   ├── .npmignore
    │   ├── README.md
    │   ├── package.json
    │   ├── src/
    │   │   ├── context.ts
    │   │   ├── hooks.ts
    │   │   ├── index.tsx
    │   │   └── provider.tsx
    │   ├── tsconfig.json
    │   └── tslint.json
    └── use-websockets/
        ├── .npmignore
        ├── README.md
        ├── package.json
        ├── src/
        │   ├── context.ts
        │   ├── hooks.ts
        │   ├── index.tsx
        │   └── provider.tsx
        ├── tsconfig.json
        └── tslint.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/test_pr.yml
================================================
# This workflow will run when a pull request event is triggered (push, open, whatever happens)
name: Node.js test
on:
  pull_request:
    branches: ['main']
  workflow_dispatch: # just in case when you need to trigger the thing manually without pull requests

jobs:
  cypress-run:
    runs-on: ubuntu-16.04
    continue-on-error: true
    steps:
      - name: Install libgconf-2-4
        run: sudo apt-get install libgconf-2-4 # Don't worry about passwords, sudo won't prompt for any, cuz there isn't a password here.
      - uses: actions/checkout@v2
      - name: Setup Node.js v10 🎁
        uses: actions/setup-node@v1
        with:
          node-version: 10.x
      - name: Install dependencies 📦
        run: npm ci
      - name: Setup cache
        uses: actions/cache@v2
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
      - name: Bootstrap 🥾
        run: npm run bootstrap
      - name: restore lerna
        uses: actions/cache@v2
        with:
          path: |
            node_modules
            */*/node_modules
          key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
      - name: Lint 🔍
        run: npm run check:lint
      - name: Build the hooks 🛠
        run: npm run build
      - name: Test the hooks ✔
        uses: cypress-io/github-action@v2
        with:
          start: npm start, npm run start:test-server

      - name: Upload the videos
        uses: actions/upload-artifact@v2
        with:
          name: cypress-videos
          path: cypress/videos/*
        
    


================================================
FILE: .gitignore
================================================
node_modules
.cache
dist
cypress/videos
lib

================================================
FILE: LICENSE.md
================================================
Copyright (c) 2004-Today Marvin Frachet

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
[![Build Status](https://travis-ci.org/mfrachet/use-socketio.svg?branch=master)](https://travis-ci.org/mfrachet/use-socketio)

React hooks for handling server-push technologies:

- [use-socketio](./packages/use-socketio) for [Socket.io](https://socket.io/)
- [use-server-sent-events](./packages/use-server-sent-events) for [Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
- [use-websockets](./packages/use-websockets) for [Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)

## Running samples

To run samples locally, you can:

```sh
$ git clone https://github.com/mfrachet/server-push-hooks
$ cd server-push-hooks
$ npm install # install lerna and dependencies at the root
$ npm run bootstrap # install lerna packages dependencies
$ npm run build # build the lerna packages
$ npm start # start the web application
$ npm start:test-server # start the backend services in another terminal
$ npm run e2e # run E2E tests of the projects in another terminal
```


================================================
FILE: cypress/fixtures/example.json
================================================
{
  "name": "Using fixtures to represent data",
  "email": "hello@cypress.io",
  "body": "Fixtures are a great way to mock data for responses to routes"
}

================================================
FILE: cypress/integration/socketio.spec.js
================================================
context("Socket.io", () => {
  beforeEach(() => {
    cy.visit("http://localhost:1234/socket-io");
  });

  describe("Last message section", () => {
    it("should be an empty section at the beginning", () => {
      cy.get("[data-cy=last-message]").invoke("text").should("eq", "");
    });

    it("should display a message in the last message section", () => {
      cy.get("[data-cy=add-one-last-message]").click();

      cy.get("[data-cy=last-message]")
        .invoke("text")
        .should("eq", "This is one new message");
    });

    it("should display only the last message in the last message section while triggering three", () => {
      cy.get("[data-cy=add-three-last-messages]").click();

      cy.get("[data-cy=last-message]")
        .invoke("text")
        .should("eq", "This is a third new message");
    });

    it("should successfully manage subscription and unsubscription for a specific event", () => {
      cy.get("[data-cy=add-one-last-message]").click();
      cy.wait(100);
      cy.get("[data-cy=unsubscribe-last-message]").click();
      cy.get("[data-cy=add-three-last-messages]").click();

      cy.get("[data-cy=last-message]")
        .invoke("text")
        .should("eq", "This is one new message");

      cy.get("[data-cy=subscribe-last-message]").click();
      cy.wait(100);
      cy.get("[data-cy=add-three-last-messages]").click();

      cy.get("[data-cy=last-message]")
        .invoke("text")
        .should("eq", "This is a third new message");
    });
  });

  describe('All "message" event messages', () => {
    beforeEach(() => {
      cy.get("[data-cy=clear-messages]").click();
    });

    it("should be an empty section at the beginning", () => {
      cy.get("[data-cy=messages]").invoke("text").should("eq", "");
    });

    it("should display 3 messages", () => {
      cy.get("[data-cy=add-three-messages]").click();

      cy.wait(100);

      cy.get("[data-cy=messages]")
        .children("li")
        .eq(2)
        .invoke("text")
        .should("eq", "This is one new message");

      cy.get("[data-cy=messages]")
        .children("li")
        .eq(1)
        .invoke("text")
        .should("eq", "This is a second new message");

      cy.get("[data-cy=messages]")
        .children("li")
        .eq(0)
        .invoke("text")
        .should("eq", "This is a third new message");
    });

    it("should manage the subscription and unsubscription flows", () => {
      cy.get("[data-cy=add-three-messages]").click();
      cy.wait(100);

      cy.get("[data-cy=messages]").children("li").its("length").should("eq", 3);

      cy.get("[data-cy=unsubscribe-messages").click();

      cy.get("[data-cy=add-three-messages]").click();
      cy.wait(100);

      cy.get("[data-cy=messages]").children("li").its("length").should("eq", 3);

      cy.get("[data-cy=subscribe-messages").click();

      cy.get("[data-cy=add-three-messages]").click();
      cy.wait(100);

      cy.get("[data-cy=messages]").children("li").its("length").should("eq", 6);
    });
  });
});


================================================
FILE: cypress/integration/sse.spec.js
================================================
context("Server sent event", () => {
  describe("Last message for SSE", () => {
    beforeEach(() => {
      cy.visit("http://localhost:1234/last-sse");
    });

    it("should be an empty section at the beginning", () => {
      cy.get("[data-cy=last-sse-message]").invoke("text").should("eq", "");
    });

    it("should have 'Marvin' as first SSE message", () => {
      cy.get("[data-cy=last-sse-message]").should("contain", "Marvin");
    });

    it("should have 'Laetitia' as second SSE message", () => {
      cy.get("[data-cy=last-sse-message]").should("contain", "Laetitia");
    });
  });

  describe("All messages from SSE", () => {
    beforeEach(() => {
      cy.visit("http://localhost:1234/all-sse");
    });

    it("should display all the names", () => {
      cy.get("[data-cy=all-sse-messages]").should("contain", "Marvin");

      cy.get("[data-cy=all-sse-messages]").should("contain", "Laetitia");
    });
  });
});


================================================
FILE: cypress/integration/websocket.spec.js
================================================
context("Socket.io", () => {
  beforeEach(() => {
    cy.visit("http://localhost:1234/websocket");
    cy.contains("Clear all messages").click();
  });

  describe("Connection", () => {
    it("should open a websocket connection", () => {
      cy.contains("Connection is opened.").should("be.visible");
    });
  });

  describe("Last message section", () => {
    beforeEach(() => {
      cy.contains("Switch to Last message").click();
    });

    it("should be an empty section at the beginning", () => {
      cy.contains("No last messages").should("be.visible");
    });

    it("should show one last message", () => {
      cy.contains("Ask for one last message").click();
      cy.contains("One last message").should("be.visible");
    });

    it("should show three last message", () => {
      cy.contains("Ask for three last messages").click();
      cy.contains("Three last message of three").should("be.visible");
    });
  });

  describe("All message section", () => {
    it("should be an empty section at the beginning", () => {
      cy.contains("No messages").should("be.visible");
    });

    it("should show three messages", () => {
      cy.contains("Ask for messages").click();
      cy.contains("One of three messages").should("be.visible");
      cy.contains("Two of three messages").should("be.visible");
      cy.contains("Three of three messages").should("be.visible");
    });
  });
});


================================================
FILE: cypress/plugins/index.js
================================================
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

module.exports = (on, config) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
}


================================================
FILE: cypress/support/commands.js
================================================
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })


================================================
FILE: cypress/support/index.js
================================================
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')


================================================
FILE: cypress.json
================================================
{
  "defaultCommandTimeout": 10000
}


================================================
FILE: example/App.js
================================================
import React from "react";
import { SocketIoExample } from "./socketio/SocketIo";
import { AllSSEMessagesExample, LastSSEMessageExample } from "./sse/SSE";
import { WebsocketExample } from "./websocket/Websocket";
import { Link, Router } from "@reach/router";

export const App = () => (
  <div>
    <nav>
      <Link to="/socket-io">SocketIo</Link>
      <Link to="/all-sse">All sse</Link>
      <Link to="/last-sse">Last sse</Link>
      <Link to="/websocket">Websockets</Link>
    </nav>

    <Router>
      <SocketIoExample path="/socket-io" />
      <AllSSEMessagesExample path="all-sse" />
      <LastSSEMessageExample path="last-sse" />
      <WebsocketExample path="/websocket" />
    </Router>
  </div>
);


================================================
FILE: example/index.html
================================================
<!DOCTYPE html>
<html>
  <head>
    <title>React starter app</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="index.js"></script>
  </body>
</html>


================================================
FILE: example/index.js
================================================
import React from "react";
import ReactDOM from "react-dom";
import { App } from "./App";

const mountNode = document.getElementById("app");

ReactDOM.render(<App />, mountNode);


================================================
FILE: example/server-helpers.js
================================================
const express = require("express");
const http = require("http");
const cors = require("cors");

const createHttpServer = () => {
  const app = express();
  const server = http.createServer(app);

  app.use(cors());

  return { server, app };
};

module.exports = createHttpServer;


================================================
FILE: example/server.js
================================================
const startSocketIoServer = require("./socketio/socketio-server");
const startSSEServer = require("./sse/sse-server");
const startWebsocketServer = require("./websocket/websocket-server");

startSocketIoServer();
startSSEServer();
startWebsocketServer();


================================================
FILE: example/socketio/SocketIo.js
================================================
import React, { useEffect, useState } from "react";
import {
  SocketIOProvider,
  useLastMessage,
  useSocket,
} from "../../packages/use-socketio";
import { port } from "./constants";

const LastMessage = () => {
  const [lastMessage, setLastMessage] = useState();
  const { data, socket, unsubscribe, subscribe } = useLastMessage(
    "last-messages"
  );

  // synchronize state with data so that we can clear it in the ui
  useEffect(() => {
    setLastMessage(data);
  }, [data]);

  return (
    <section>
      <h3>Last message</h3>
      <button
        data-cy="clear-last-message"
        onClick={() => setLastMessage(undefined)}
      >
        Clear last messages
      </button>
      <button data-cy="unsubscribe-last-message" onClick={unsubscribe}>
        Unsubscribe last messages
      </button>
      <button data-cy="subscribe-last-message" onClick={subscribe}>
        Subscribe last messages
      </button>
      <button
        onClick={() => socket.emit("one-last-message")}
        data-cy="add-one-last-message"
      >
        Ask the server to emit one new message
      </button>

      <button
        onClick={() => socket.emit("three-last-messages")}
        data-cy="add-three-last-messages"
      >
        Ask the server to emit three new messages
      </button>
      <p data-cy="last-message">{lastMessage}</p>
    </section>
  );
};

const Message = () => {
  const [messages, setMessages] = useState([]);

  const { socket, subscribe, unsubscribe } = useSocket(
    "new-message",
    (newMessage) => setMessages([newMessage, ...messages])
  );

  return (
    <section>
      <h3>All tweets</h3>

      <button onClick={() => setMessages([])} data-cy="clear-messages">
        Clear messages
      </button>

      <button onClick={unsubscribe} data-cy="unsubscribe-messages">
        Unsubscribe
      </button>

      <button onClick={subscribe} data-cy="subscribe-messages">
        Subscribe
      </button>

      <button
        onClick={() => socket.emit("three-messages")}
        data-cy="add-three-messages"
      >
        Ask the server to emit three new messages
      </button>
      <ul data-cy="messages">
        {messages.map((message, index) => (
          <li key={index}>{message}</li>
        ))}
      </ul>
    </section>
  );
};

export const SocketIoExample = () => (
  <SocketIOProvider url={`http://localhost:${port}`}>
    <LastMessage />
    <Message />
  </SocketIOProvider>
);


================================================
FILE: example/socketio/constants.js
================================================
module.exports = {
  port: 3000,
};


================================================
FILE: example/socketio/socketio-server.js
================================================
const socketIo = require("socket.io");
const createHttpServer = require("../server-helpers");
const { port } = require("./constants");

const startSocketIoServer = () => {
  const { server: socketIoServer } = createHttpServer();
  const io = socketIo(socketIoServer, { 
    cors: {
      origin: "http://localhost:1234",
      methods: ["GET", "POST"]
    }
  });

  io.on("connection", function (socket) {
    socket.on("one-last-message", () => {
      socket.emit("last-messages", "This is one new message");
    });

    socket.on("three-last-messages", () => {
      socket.emit("last-messages", "This is one new message");
      socket.emit("last-messages", "This is a second new message");
      socket.emit("last-messages", "This is a third new message");
    });

    socket.on("three-messages", () => {
      socket.emit("new-message", "This is one new message");
      socket.emit("new-message", "This is a second new message");
      socket.emit("new-message", "This is a third new message");
    });
  });

  socketIoServer.listen(port, () =>
    console.log(`[Socket.io] Started on port :${port}`)
  );
};

module.exports = startSocketIoServer;


================================================
FILE: example/sse/SSE.js
================================================
import React, { useState } from "react";
import {
  useLastSSE,
  useSSE,
  SSEProvider,
} from "../../packages/use-server-sent-events";
import { port } from "./constants";

export const LastSSEMessage = () => {
  const { data } = useLastSSE();

  return (
    <section>
      <h3>Last SSE Message</h3>
      <p data-cy="last-sse-message">{data && data.name}</p>
    </section>
  );
};

export const AllSSEMessages = () => {
  const [names, setNames] = useState([]);

  useSSE((nextName) => setNames([...names, nextName]));

  return (
    <section>
      <h3>All SSE messages</h3>
      <ul data-cy="all-sse-messages">
        {names.map(({ name }) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </section>
  );
};

export const LastSSEMessageExample = () => {
  return (
    <SSEProvider url={`http://localhost:${port}/last-sse`}>
      <LastSSEMessage />
    </SSEProvider>
  );
};

export const AllSSEMessagesExample = () => {
  return (
    <SSEProvider url={`http://localhost:${port}/all-sse`}>
      <AllSSEMessages />
    </SSEProvider>
  );
};


================================================
FILE: example/sse/constants.js
================================================
module.exports = {
  port: 3123,
};


================================================
FILE: example/sse/sse-server.js
================================================
const createHttpServer = require("../server-helpers");
const { port } = require("./constants");

const sseRequestHandler = (req, res) => {
  res.set("Content-Type", "text/event-stream");

  const firstData = { name: "Marvin" };

  res.write(`data: ${JSON.stringify(firstData)}`);
  res.write("\n\n");

  setTimeout(() => {
    const secondData = { name: "Laetitia" };

    res.write(`data: ${JSON.stringify(secondData)}`);
    res.write("\n\n");
  }, 500);
};

const startSSEServer = () => {
  const { server: sseServer, app: appSSE } = createHttpServer();

  appSSE.get("/last-sse", sseRequestHandler);
  appSSE.get("/all-sse", sseRequestHandler);

  sseServer.listen(port, () => {
    console.log(`[SSE] Started on port :${port}`);
  });
};

module.exports = startSSEServer;


================================================
FILE: example/websocket/Websocket.js
================================================
import React from "react";
import {
  WebSocketProvider,
  useWebsocket,
  useLastWebsocketMessage,
} from "../../packages/use-websockets";
import { port } from "./constants";

const LastMessage = () => {
  const { data, ws } = useLastWebsocketMessage();

  return (
    <div>
      <h3>Last message</h3>
      <button onClick={() => ws.send("one-last")}>
        Ask for one last message
      </button>
      <button onClick={() => ws.send("three-last-messages")}>
        Ask for three last messages
      </button>
      {data?.message || "No last messages"}
    </div>
  );
};

const AllMessages = () => {
  const [messages, setMessages] = React.useState([]);
  const { ws } = useWebsocket((d) => setMessages([...messages, d.message]));

  return (
    <div>
      <h3>All messages</h3>

      <button onClick={() => setMessages([])}>Clear all messages</button>
      <button onClick={() => ws.send("all-messages")}>Ask for messages</button>

      {messages.length === 0 && <>No messages</>}
      {messages.length > 0 && (
        <ul>
          {messages.map((msg, index) => (
            <li key={index}>{msg}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export const WebsocketExample = () => {
  const [isOpened, setIsOpened] = React.useState(false);
  const [tab, setTab] = React.useState("all");

  return (
    <WebSocketProvider
      url={`ws://localhost:${port}/`}
      onOpen={() => setIsOpened(true)}
    >
      <p>Connection is {isOpened ? "opened" : "closed"}.</p>

      <button onClick={() => setTab("all")}>Switch to All message</button>
      <button onClick={() => setTab("last")}>Switch to Last message</button>

      {tab === "all" && <AllMessages />}
      {tab !== "all" && <LastMessage />}
    </WebSocketProvider>
  );
};


================================================
FILE: example/websocket/constants.js
================================================
module.exports = {
  port: 3124,
};


================================================
FILE: example/websocket/websocket-server.js
================================================
const WebSocket = require("ws");
const createHttpServer = require("../server-helpers");
const { port } = require("./constants");

const startWebsocketServer = () => {
  const { server } = createHttpServer();
  const wss = new WebSocket.Server({ server });

  wss.on("connection", function connection(ws) {
    const sendMessage = (type, message) => {
      ws.send(JSON.stringify({ type, message }));
    };

    ws.on("message", function incoming(message) {
      switch (message) {
        case "one-last":
          sendMessage("one-last", "One last message");
          break;

        case "three-last-messages":
          sendMessage("three-last-messages", "One last message of three");
          sendMessage("three-last-messages", "Two last message of three");
          sendMessage("three-last-messages", "Three last message of three");
          break;

        case "all-messages":
          sendMessage("all-messages", "One of three messages");
          sendMessage("all-messages", "Two of three messages");
          sendMessage("all-messages", "Three of three messages");
          break;
      }
    });

    ws.send("Opened from the server");
  });

  server.listen(port, () => {
    console.log(`[Websocket] Started on port :${port}`);
  });
};

module.exports = startWebsocketServer;


================================================
FILE: lerna.json
================================================
{
  "packages": [
    "packages/*"
  ],
  "version": "2.1.1"
}


================================================
FILE: package.json
================================================
{
  "name": "root",
  "private": true,
  "scripts": {
    "bootstrap": "lerna bootstrap",
    "e2e:ci": "cypress run",
    "e2e": "cypress open",
    "build": "lerna run build",
    "format": "lerna run format",
    "lint": "lerna run lint",
    "check:lint": "lerna run check:lint",
    "start": "parcel example/index.html",
    "start:test-server": "node ./example/server",
    "release": "npm i && npm run bootstrap && npm run check:lint && npm run build && lerna version && lerna publish"
  },
  "devDependencies": {
    "@reach/router": "^1.3.4",
    "cors": "^2.8.5",
    "cypress": "^5.2.0",
    "express": "^4.17.1",
    "lerna": "^3.22.1",
    "parcel-bundler": "^1.12.4",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "socket.io": "^3.0.3",
    "ws": "^7.3.1"
  }
}


================================================
FILE: packages/use-server-sent-events/.npmignore
================================================
example
cypress
src
node_modules
dist
.cache

================================================
FILE: packages/use-server-sent-events/README.md
================================================
Use [Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) with React, in hooks (React v16.8+).

# Usage

## Installation

```sh
$ yarn add use-server-sent-events
```

## In your code

### useSSE hook

Listen to a specific event and trigger the according callback every time there's one. **This hooks doesn't trigger a re-render. You have to manage it yourself.**

```jsx
import { SSEProvider, useSSE } from "use-server-sent-events";

const Parent = () => (
  <SSEProvider
    url="http://localhost:3000/last-sse"
    onOpen={() => console.log("connection opened")}
  >
    <Children />
  </SSEProvider>
);

const Children = () => {
  const [messages, setMessages] = useState([]);
  const error = useSSE((nextMessage) =>
    setMessages([...messages, nextMessage])
  );

  return (
    <ul>
      {messages.map((msg, index) => (
        <li key={index}>{msg}</li>
      ))}
    </ul>
  );
};
```

### useLastSSE hook

Listen to the latest message received on a specific event name. **This hook triggers a re-render so you don't have to.**

```jsx
import { SSEProvider, useLastSSE } from "use-server-sent-events";

const Parent = () => (
  <SSEProvider url="http://localhost:3000/sse">
    <Children />
  </SSEProvider>
);

const Children = () => {
  const { data, error } = useLastSSE();

  return <p>{data || "No message yet"}</p>;
};
```

## Notes

For example on how to implement a Server Sent Event server, you can take a look at the [Server Sent Event example folder](../../example/sse/sse-server.js).


================================================
FILE: packages/use-server-sent-events/package.json
================================================
{
  "name": "use-server-sent-events",
  "version": "2.1.0",
  "description": "React hooks for https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events",
  "main": "./lib/index.js",
  "author": "Marvin Frachet <marvin.frachet@gmail.com>",
  "license": "MIT",
  "private": false,
  "homepage": "https://github.com/mfrachet/server-push-hooks",
  "repository": {
    "type": "git",
    "url": "https://github.com/mfrachet/server-push-hooks"
  },
  "keywords": [
    "react",
    "context"
  ],
  "scripts": {
    "build": "yarn lint && tsc --outDir lib",
    "format": "prettier --write './src/**/*.tsx'",
    "lint": "tslint -c tslint.json 'src/**/**'",
    "check:lint": "tsc --noEmit && yarn lint"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "@types/react": "^16.9.49",
    "@types/react-dom": "^16.9.8",
    "prettier": "^2.1.2",
    "tslint": "^6.1.3",
    "tslint-config-prettier": "^1.18.0",
    "tslint-plugin-prettier": "^2.3.0",
    "typescript": "^4.0.3"
  },
  "peerDependencies": {
    "react": "^16.13.1"
  }
}


================================================
FILE: packages/use-server-sent-events/src/context.ts
================================================
import { createContext } from "react";

export const SSEContext = createContext<EventSource>(undefined);


================================================
FILE: packages/use-server-sent-events/src/hooks.ts
================================================
import { useContext, useEffect, useRef, useState } from "react";
import { SSEContext } from "./context";

export const useLastSSE = () => {
  const [data, setData] = useState(undefined);
  const [error, setError] = useState(undefined);

  const eventSource = useContext(SSEContext);

  useEffect(() => {
    eventSource.onmessage = (e) => {
      let message;

      try {
        message = JSON.parse(e.data);
      } catch {
        message = e.data;
      }

      setData(message);
    };

    eventSource.onerror = (e) => {
      setError(e);
    };
  }, []);

  return { data, error };
};

export const useSSE = (onMessage: (data: JSON) => void) => {
  const [error, setError] = useState(undefined);
  const onMessageRef = useRef(undefined);

  onMessageRef.current = onMessage;

  const eventSource = useContext(SSEContext);

  useEffect(() => {
    eventSource.onmessage = (e) => {
      let message;

      try {
        message = JSON.parse(e.data);
      } catch {
        message = e.data;
      }

      onMessageRef.current(message);
    };

    eventSource.onerror = (e) => {
      setError(e);
    };
  }, []);

  return error;
};


================================================
FILE: packages/use-server-sent-events/src/index.tsx
================================================
export * from "./context";
export * from "./provider";
export * from "./hooks";


================================================
FILE: packages/use-server-sent-events/src/provider.tsx
================================================
import * as React from "react";
import { SSEContext } from "./context";

export interface ISSEProviderProps {
  url: string;
  opts?: EventSourceInit;
  onOpen?: (ev: Event) => void;
}

export const SSEProvider: React.FC<ISSEProviderProps> = ({
  url,
  opts,
  children,
  onOpen,
}) => {
  const eventSourceRef = React.useRef<EventSource>();
  const onOpenRef = React.useRef<(ev: Event) => void>();

  if (!window) {
    return <>{children}</>;
  }

  if (!eventSourceRef.current) {
    eventSourceRef.current = new EventSource(url, opts);
  }

  onOpenRef.current = onOpen;

  React.useEffect(() => {
    if (onOpenRef?.current) {
      eventSourceRef.current.onopen = onOpenRef.current;
    }

    return () => {
      eventSourceRef?.current?.close();
    };
  }, []);

  return (
    <SSEContext.Provider value={eventSourceRef.current}>
      {children}
    </SSEContext.Provider>
  );
};


================================================
FILE: packages/use-server-sent-events/tsconfig.json
================================================
{
  "compilerOptions": {
    "declaration": true,
    "esModuleInterop": true,
    "jsx": "react",
    "module": "commonjs",
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "skipLibCheck": true
  },
  "exclude": [],
  "include": ["./src/**/*"]
}


================================================
FILE: packages/use-server-sent-events/tslint.json
================================================
{
  "extends": [
    "tslint:latest",
    "tslint-plugin-prettier",
    "tslint-config-prettier"
  ],
  "jsRules": {},
  "rules": {},
  "rulesDirectory": []
}


================================================
FILE: packages/use-socketio/.npmignore
================================================
example
cypress
src
node_modules
dist
.cache

================================================
FILE: packages/use-socketio/README.md
================================================
Use [socket.io v3](https://socket.io/) with React, in hooks (React v16.8+).

_If you want to use socket.io in v2, you might want to use the v2.0.4 of this package. The last commit related to the v2 version is [this one](https://github.com/mfrachet/server-push-hooks/tree/4636e16f6753c5a49a52b0091ec92fce44e9913b)._

# Usage

## Installation

```sh
$ yarn add use-socketio
```

## In your code

### useSocket hook

Listen to a specific event and trigger the according callback every time there's one. **This hooks doesn't trigger a re-render. You have to manage it yourself.**

```jsx
import { SocketIOProvider, useSocket } from "use-socketio";

const Twitter = () => {
  const [tweets, setTweet] = useState([]);

  const { socket, subscribe, unsubscribe } = useSocket("tweet", (newTweet) =>
    setTweet([newTweet, ...tweets])
  );

  return tweets.length ? (
    <ul>
      {tweets.map((tweet) => (
        <li key={tweet.id}>{tweet.text}</li>
      ))}
    </ul>
  ) : (
    <p>Actually waiting for the websocket server...</p>
  );
};

const App = () => (
  <SocketIOProvider url="http://localhost:3000" opts={socketIoOptions}>
    <Twitter />
  </SocketIOProvider>
);
```

_The socketio options to pass to the provider are available here: https://socket.io/docs/client-api/#new-Manager-url-options._

### useLastMessage hook

Listen to the latest message received on a specific event name. **This hook triggers a re-render so you don't have to.**

```jsx
import { SocketIOProvider, useLastMessage } from "use-socketio";

const Twitter = () => {
  const { data: lastMessage, socket, subscribe, unsubscribe } = useLastMessage(
    "tweet"
  );

  return <p>{lastMessage || "Waiting for some tweets"}</p>;
};

const App = () => (
  <SocketIOProvider url="http://localhost:3000">
    <Twitter />
  </SocketIOProvider>
);
```

## Notes

For example on how to implement a Socket.io server, you can take a look at the [socket.io the example folder](../../example/socketio/socketio-server.js).


================================================
FILE: packages/use-socketio/package.json
================================================
{
  "name": "use-socketio",
  "version": "2.1.0",
  "description": "React hooks for https://socket.io/",
  "main": "./lib/index.js",
  "author": "Marvin Frachet <marvin.frachet@gmail.com>",
  "license": "MIT",
  "private": false,
  "homepage": "https://github.com/mfrachet/server-push-hooks",
  "repository": {
    "type": "git",
    "url": "https://github.com/mfrachet/server-push-hooks"
  },
  "keywords": [
    "react",
    "context"
  ],
  "scripts": {
    "build": "yarn lint && tsc --outDir lib",
    "format": "prettier --write './src/**/*.tsx'",
    "lint": "tslint -c tslint.json 'src/**/**'",
    "check:lint": "tsc --noEmit && yarn lint"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "@types/react": "^16.9.49",
    "@types/react-dom": "^16.9.8",
    "@types/socket.io-client": "^1.4.33",
    "prettier": "^2.1.2",
    "tslint": "^6.1.3",
    "tslint-config-prettier": "^1.18.0",
    "tslint-plugin-prettier": "^2.3.0",
    "typescript": "^4.0.3"
  },
  "peerDependencies": {
    "react": "^16.13.1"
  },
  "dependencies": {
    "socket.io-client": "^3.0.3"
  }
}


================================================
FILE: packages/use-socketio/src/context.ts
================================================
import { createContext } from "react";

export const SocketIOContext = createContext<SocketIOClient.Socket>(undefined);


================================================
FILE: packages/use-socketio/src/hooks.ts
================================================
import { useContext, useEffect, useRef, useState } from "react";
import { SocketIOContext } from "./context";

export const useSocket = (
  eventKey?: string,
  callback?: (...args: any) => void
) => {
  const socket = useContext(SocketIOContext);
  const callbackRef = useRef(callback);

  callbackRef.current = callback;

  const socketHandlerRef = useRef(function() {
    if (callbackRef.current) {
      callbackRef.current.apply(this, arguments);
    }
  });

  const subscribe = () => {
    if (eventKey) {
      socket.on(eventKey, socketHandlerRef.current);
    }
  };

  const unsubscribe = () => {
    if (eventKey) {
      socket.removeListener(eventKey, socketHandlerRef.current);
    }
  };

  useEffect(() => {
    subscribe();

    return unsubscribe;
  }, [eventKey]);

  return { socket, unsubscribe, subscribe };
};

export const useLastMessage = (eventKey: string) => {
  const socket = useContext(SocketIOContext);
  const [data, setData] = useState();

  const subscribe = () => {
    if (eventKey) {
      socket.on(eventKey, setData);
    }
  };

  const unsubscribe = () => {
    if (eventKey) {
      socket.removeListener(eventKey, setData);
    }
  };

  useEffect(() => {
    subscribe();

    return unsubscribe;
  }, [eventKey]);

  return { data, socket, unsubscribe, subscribe };
};


================================================
FILE: packages/use-socketio/src/index.tsx
================================================
export * from "./context";
export * from "./provider";
export * from "./hooks";


================================================
FILE: packages/use-socketio/src/provider.tsx
================================================
import * as React from "react";
import io from "socket.io-client";
import { SocketIOContext } from "./context";

export interface ISocketIOProviderProps {
  url: string;
  opts?: SocketIOClient.ConnectOpts;
}

export const SocketIOProvider: React.FC<ISocketIOProviderProps> = ({
  url,
  opts,
  children,
}) => {
  const socketRef = React.useRef<SocketIOClient.Socket>();

  if (typeof window === "undefined") {
    return <>{children}</>;
  }

  if (!socketRef.current) {
    socketRef.current = io(url, opts || {});
  }

  return (
    <SocketIOContext.Provider value={socketRef.current}>
      {children}
    </SocketIOContext.Provider>
  );
};


================================================
FILE: packages/use-socketio/tsconfig.json
================================================
{
  "compilerOptions": {
    "declaration": true,
    "esModuleInterop": true,
    "jsx": "react",
    "module": "commonjs",
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "skipLibCheck": true
  },
  "exclude": [],
  "include": ["./src/**/*"]
}


================================================
FILE: packages/use-socketio/tslint.json
================================================
{
  "extends": [
    "tslint:latest",
    "tslint-plugin-prettier",
    "tslint-config-prettier"
  ],
  "jsRules": {},
  "rules": {},
  "rulesDirectory": []
}


================================================
FILE: packages/use-websockets/.npmignore
================================================
example
cypress
src
node_modules
dist
.cache

================================================
FILE: packages/use-websockets/README.md
================================================
Use [Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) with React, in hooks (React v16.8+).

# Usage

## Installation

```sh
$ yarn add use-websockets
```

## In your code

### useWebsocket hook

Listen to a specific event and trigger the according callback every time there's one. **This hooks doesn't trigger a re-render. You have to manage it yourself.**

```jsx
import { WebsocketProvider, useWebsocket } from "use-websockets";

const Parent = () => (
  <WebsocketProvider
    url="wss://localhost:3000/"
    onOpen={() => console.log("connection opened")}
  >
    <Children />
  </WebsocketProvider>
);

const Children = () => {
  const [messages, setMessages] = useState([]);
  const { ws, error } = useWebsocket((nextMessage) =>
    setMessages([...messages, nextMessage])
  );

  return (
    <ul>
      {messages.map((msg, index) => (
        <li key={index}>{msg}</li>
      ))}
    </ul>
  );
};
```

### useLastWebsocketMessage hook

Listen to the latest message received on a specific event name. **This hook triggers a re-render so you don't have to.**

```jsx
import { WebsocketProvider, useLastWebsocketMessage } from "use-websockets";

const Parent = () => (
  <WebsocketProvider url="wss://localhost:3000/">
    <Children />
  </WebsocketProvider>
);

const Children = () => {
  const { data, error, ws } = useLastWebsocketMessage();

  return <p>{data || "No message yet"}</p>;
};
```

## Notes

For example on how to implement a Websocket server, you can take a look at the [Websocket example folder](../../example/websocket/websocket-server.js).


================================================
FILE: packages/use-websockets/package.json
================================================
{
  "name": "use-websockets",
  "version": "2.1.1",
  "description": "React hooks for https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API",
  "main": "./lib/index.js",
  "author": "Marvin Frachet <marvin.frachet@gmail.com>",
  "license": "MIT",
  "private": false,
  "homepage": "https://github.com/mfrachet/server-push-hooks",
  "repository": {
    "type": "git",
    "url": "https://github.com/mfrachet/server-push-hooks"
  },
  "keywords": [
    "react",
    "context"
  ],
  "scripts": {
    "build": "yarn lint && tsc --outDir lib",
    "format": "prettier --write './src/**/*.tsx'",
    "lint": "tslint -c tslint.json 'src/**/**'",
    "check:lint": "tsc --noEmit && yarn lint"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "@types/react": "^16.9.49",
    "@types/react-dom": "^16.9.8",
    "prettier": "^2.1.2",
    "tslint": "^6.1.3",
    "tslint-config-prettier": "^1.18.0",
    "tslint-plugin-prettier": "^2.3.0",
    "typescript": "^4.0.3"
  },
  "peerDependencies": {
    "react": "^16.13.1"
  }
}


================================================
FILE: packages/use-websockets/src/context.ts
================================================
import { createContext } from "react";

export const WebsocketContext = createContext<WebSocket>(undefined);


================================================
FILE: packages/use-websockets/src/hooks.ts
================================================
import { useContext, useEffect, useRef, useState } from "react";
import { WebsocketContext } from "./context";

export const useLastWebsocketMessage = () => {
  const [data, setData] = useState(undefined);
  const [error, setError] = useState(undefined);

  const ws = useContext(WebsocketContext);

  useEffect(() => {
    ws.onmessage = (e) => {
      let message;

      try {
        message = JSON.parse(e.data);
      } catch {
        message = e.data;
      }

      setData(message);
    };

    ws.onerror = (e) => {
      setError(e);
    };
  }, []);

  return { data, error, ws };
};

export const useWebsocket = <T extends unknown>(onMessage: (data: T) => void) => {
  const [error, setError] = useState(undefined);
  const onMessageRef = useRef(undefined);

  onMessageRef.current = onMessage;

  const ws = useContext(WebsocketContext);

  useEffect(() => {
    ws.onmessage = (event) => {
      let message;

      try {
        message = JSON.parse(event.data);
      } catch {
        message = event.data;
      }

      onMessageRef.current(message);
    };

    ws.onerror = (e) => {
      setError(e);
    };
  }, []);

  return { error, ws };
};


================================================
FILE: packages/use-websockets/src/index.tsx
================================================
export * from "./context";
export * from "./provider";
export * from "./hooks";


================================================
FILE: packages/use-websockets/src/provider.tsx
================================================
import * as React from "react";
import { WebsocketContext } from "./context";

export interface IWebSocketProviderProps {
  url: string;
  protocols?: string | string[];
  onOpen?: (ev: Event) => void;
}

export const WebSocketProvider: React.FC<IWebSocketProviderProps> = ({
  url,
  protocols,
  children,
  onOpen,
}) => {
  const ws = React.useRef<WebSocket>();
  const onOpenRef = React.useRef<(ev: Event) => void>();

  if (!window) {
    return <>{children}</>;
  }

  if (!ws.current) {
    ws.current = new WebSocket(url, protocols);
  }

  onOpenRef.current = onOpen;

  React.useEffect(() => {
    if (onOpenRef?.current) {
      ws.current.onopen = onOpenRef.current;
    }

    return () => {
      ws?.current?.close();
    };
  }, []);

  return (
    <WebsocketContext.Provider value={ws.current}>
      {children}
    </WebsocketContext.Provider>
  );
};


================================================
FILE: packages/use-websockets/tsconfig.json
================================================
{
  "compilerOptions": {
    "declaration": true,
    "esModuleInterop": true,
    "jsx": "react",
    "module": "commonjs",
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "skipLibCheck": true
  },
  "exclude": [],
  "include": ["./src/**/*"]
}


================================================
FILE: packages/use-websockets/tslint.json
================================================
{
  "extends": [
    "tslint:latest",
    "tslint-plugin-prettier",
    "tslint-config-prettier"
  ],
  "jsRules": {},
  "rules": {},
  "rulesDirectory": []
}
Download .txt
gitextract_ge2hlk0j/

├── .github/
│   └── workflows/
│       └── test_pr.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── cypress/
│   ├── fixtures/
│   │   └── example.json
│   ├── integration/
│   │   ├── socketio.spec.js
│   │   ├── sse.spec.js
│   │   └── websocket.spec.js
│   ├── plugins/
│   │   └── index.js
│   └── support/
│       ├── commands.js
│       └── index.js
├── cypress.json
├── example/
│   ├── App.js
│   ├── index.html
│   ├── index.js
│   ├── server-helpers.js
│   ├── server.js
│   ├── socketio/
│   │   ├── SocketIo.js
│   │   ├── constants.js
│   │   └── socketio-server.js
│   ├── sse/
│   │   ├── SSE.js
│   │   ├── constants.js
│   │   └── sse-server.js
│   └── websocket/
│       ├── Websocket.js
│       ├── constants.js
│       └── websocket-server.js
├── lerna.json
├── package.json
└── packages/
    ├── use-server-sent-events/
    │   ├── .npmignore
    │   ├── README.md
    │   ├── package.json
    │   ├── src/
    │   │   ├── context.ts
    │   │   ├── hooks.ts
    │   │   ├── index.tsx
    │   │   └── provider.tsx
    │   ├── tsconfig.json
    │   └── tslint.json
    ├── use-socketio/
    │   ├── .npmignore
    │   ├── README.md
    │   ├── package.json
    │   ├── src/
    │   │   ├── context.ts
    │   │   ├── hooks.ts
    │   │   ├── index.tsx
    │   │   └── provider.tsx
    │   ├── tsconfig.json
    │   └── tslint.json
    └── use-websockets/
        ├── .npmignore
        ├── README.md
        ├── package.json
        ├── src/
        │   ├── context.ts
        │   ├── hooks.ts
        │   ├── index.tsx
        │   └── provider.tsx
        ├── tsconfig.json
        └── tslint.json
Download .txt
SYMBOL INDEX (3 symbols across 3 files)

FILE: packages/use-server-sent-events/src/provider.tsx
  type ISSEProviderProps (line 4) | interface ISSEProviderProps {

FILE: packages/use-socketio/src/provider.tsx
  type ISocketIOProviderProps (line 5) | interface ISocketIOProviderProps {

FILE: packages/use-websockets/src/provider.tsx
  type IWebSocketProviderProps (line 4) | interface IWebSocketProviderProps {
Condensed preview — 55 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (45K chars).
[
  {
    "path": ".github/workflows/test_pr.yml",
    "chars": 1642,
    "preview": "# This workflow will run when a pull request event is triggered (push, open, whatever happens)\nname: Node.js test\non:\n  "
  },
  {
    "path": ".gitignore",
    "chars": 43,
    "preview": "node_modules\n.cache\ndist\ncypress/videos\nlib"
  },
  {
    "path": "LICENSE.md",
    "chars": 1064,
    "preview": "Copyright (c) 2004-Today Marvin Frachet\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of"
  },
  {
    "path": "README.md",
    "chars": 1050,
    "preview": "[![Build Status](https://travis-ci.org/mfrachet/use-socketio.svg?branch=master)](https://travis-ci.org/mfrachet/use-sock"
  },
  {
    "path": "cypress/fixtures/example.json",
    "chars": 154,
    "preview": "{\n  \"name\": \"Using fixtures to represent data\",\n  \"email\": \"hello@cypress.io\",\n  \"body\": \"Fixtures are a great way to mo"
  },
  {
    "path": "cypress/integration/socketio.spec.js",
    "chars": 3040,
    "preview": "context(\"Socket.io\", () => {\n  beforeEach(() => {\n    cy.visit(\"http://localhost:1234/socket-io\");\n  });\n\n  describe(\"La"
  },
  {
    "path": "cypress/integration/sse.spec.js",
    "chars": 939,
    "preview": "context(\"Server sent event\", () => {\n  describe(\"Last message for SSE\", () => {\n    beforeEach(() => {\n      cy.visit(\"h"
  },
  {
    "path": "cypress/integration/websocket.spec.js",
    "chars": 1417,
    "preview": "context(\"Socket.io\", () => {\n  beforeEach(() => {\n    cy.visit(\"http://localhost:1234/websocket\");\n    cy.contains(\"Clea"
  },
  {
    "path": "cypress/plugins/index.js",
    "chars": 644,
    "preview": "// ***********************************************************\n// This example plugins/index.js can be used to load plug"
  },
  {
    "path": "cypress/support/commands.js",
    "chars": 838,
    "preview": "// ***********************************************\n// This example commands.js shows you how to\n// create various custom"
  },
  {
    "path": "cypress/support/index.js",
    "chars": 670,
    "preview": "// ***********************************************************\n// This example support/index.js is processed and\n// load"
  },
  {
    "path": "cypress.json",
    "chars": 37,
    "preview": "{\n  \"defaultCommandTimeout\": 10000\n}\n"
  },
  {
    "path": "example/App.js",
    "chars": 715,
    "preview": "import React from \"react\";\nimport { SocketIoExample } from \"./socketio/SocketIo\";\nimport { AllSSEMessagesExample, LastSS"
  },
  {
    "path": "example/index.html",
    "chars": 168,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>React starter app</title>\n  </head>\n  <body>\n    <div id=\"app\"></div>\n    <sc"
  },
  {
    "path": "example/index.js",
    "chars": 179,
    "preview": "import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { App } from \"./App\";\n\nconst mountNode = document.ge"
  },
  {
    "path": "example/server-helpers.js",
    "chars": 282,
    "preview": "const express = require(\"express\");\nconst http = require(\"http\");\nconst cors = require(\"cors\");\n\nconst createHttpServer "
  },
  {
    "path": "example/server.js",
    "chars": 255,
    "preview": "const startSocketIoServer = require(\"./socketio/socketio-server\");\nconst startSSEServer = require(\"./sse/sse-server\");\nc"
  },
  {
    "path": "example/socketio/SocketIo.js",
    "chars": 2453,
    "preview": "import React, { useEffect, useState } from \"react\";\nimport {\n  SocketIOProvider,\n  useLastMessage,\n  useSocket,\n} from \""
  },
  {
    "path": "example/socketio/constants.js",
    "chars": 36,
    "preview": "module.exports = {\n  port: 3000,\n};\n"
  },
  {
    "path": "example/socketio/socketio-server.js",
    "chars": 1159,
    "preview": "const socketIo = require(\"socket.io\");\nconst createHttpServer = require(\"../server-helpers\");\nconst { port } = require(\""
  },
  {
    "path": "example/sse/SSE.js",
    "chars": 1076,
    "preview": "import React, { useState } from \"react\";\nimport {\n  useLastSSE,\n  useSSE,\n  SSEProvider,\n} from \"../../packages/use-serv"
  },
  {
    "path": "example/sse/constants.js",
    "chars": 36,
    "preview": "module.exports = {\n  port: 3123,\n};\n"
  },
  {
    "path": "example/sse/sse-server.js",
    "chars": 777,
    "preview": "const createHttpServer = require(\"../server-helpers\");\nconst { port } = require(\"./constants\");\n\nconst sseRequestHandler"
  },
  {
    "path": "example/websocket/Websocket.js",
    "chars": 1773,
    "preview": "import React from \"react\";\nimport {\n  WebSocketProvider,\n  useWebsocket,\n  useLastWebsocketMessage,\n} from \"../../packag"
  },
  {
    "path": "example/websocket/constants.js",
    "chars": 36,
    "preview": "module.exports = {\n  port: 3124,\n};\n"
  },
  {
    "path": "example/websocket/websocket-server.js",
    "chars": 1302,
    "preview": "const WebSocket = require(\"ws\");\nconst createHttpServer = require(\"../server-helpers\");\nconst { port } = require(\"./cons"
  },
  {
    "path": "lerna.json",
    "chars": 63,
    "preview": "{\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"version\": \"2.1.1\"\n}\n"
  },
  {
    "path": "package.json",
    "chars": 788,
    "preview": "{\n  \"name\": \"root\",\n  \"private\": true,\n  \"scripts\": {\n    \"bootstrap\": \"lerna bootstrap\",\n    \"e2e:ci\": \"cypress run\",\n "
  },
  {
    "path": "packages/use-server-sent-events/.npmignore",
    "chars": 44,
    "preview": "example\ncypress\nsrc\nnode_modules\ndist\n.cache"
  },
  {
    "path": "packages/use-server-sent-events/README.md",
    "chars": 1567,
    "preview": "Use [Server Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) w"
  },
  {
    "path": "packages/use-server-sent-events/package.json",
    "chars": 1149,
    "preview": "{\n  \"name\": \"use-server-sent-events\",\n  \"version\": \"2.1.0\",\n  \"description\": \"React hooks for https://developer.mozilla."
  },
  {
    "path": "packages/use-server-sent-events/src/context.ts",
    "chars": 105,
    "preview": "import { createContext } from \"react\";\n\nexport const SSEContext = createContext<EventSource>(undefined);\n"
  },
  {
    "path": "packages/use-server-sent-events/src/hooks.ts",
    "chars": 1147,
    "preview": "import { useContext, useEffect, useRef, useState } from \"react\";\nimport { SSEContext } from \"./context\";\n\nexport const u"
  },
  {
    "path": "packages/use-server-sent-events/src/index.tsx",
    "chars": 80,
    "preview": "export * from \"./context\";\nexport * from \"./provider\";\nexport * from \"./hooks\";\n"
  },
  {
    "path": "packages/use-server-sent-events/src/provider.tsx",
    "chars": 895,
    "preview": "import * as React from \"react\";\nimport { SSEContext } from \"./context\";\n\nexport interface ISSEProviderProps {\n  url: str"
  },
  {
    "path": "packages/use-server-sent-events/tsconfig.json",
    "chars": 261,
    "preview": "{\n  \"compilerOptions\": {\n    \"declaration\": true,\n    \"esModuleInterop\": true,\n    \"jsx\": \"react\",\n    \"module\": \"common"
  },
  {
    "path": "packages/use-server-sent-events/tslint.json",
    "chars": 159,
    "preview": "{\n  \"extends\": [\n    \"tslint:latest\",\n    \"tslint-plugin-prettier\",\n    \"tslint-config-prettier\"\n  ],\n  \"jsRules\": {},\n "
  },
  {
    "path": "packages/use-socketio/.npmignore",
    "chars": 44,
    "preview": "example\ncypress\nsrc\nnode_modules\ndist\n.cache"
  },
  {
    "path": "packages/use-socketio/README.md",
    "chars": 1989,
    "preview": "Use [socket.io v3](https://socket.io/) with React, in hooks (React v16.8+).\n\n_If you want to use socket.io in v2, you mi"
  },
  {
    "path": "packages/use-socketio/package.json",
    "chars": 1165,
    "preview": "{\n  \"name\": \"use-socketio\",\n  \"version\": \"2.1.0\",\n  \"description\": \"React hooks for https://socket.io/\",\n  \"main\": \"./li"
  },
  {
    "path": "packages/use-socketio/src/context.ts",
    "chars": 120,
    "preview": "import { createContext } from \"react\";\n\nexport const SocketIOContext = createContext<SocketIOClient.Socket>(undefined);\n"
  },
  {
    "path": "packages/use-socketio/src/hooks.ts",
    "chars": 1315,
    "preview": "import { useContext, useEffect, useRef, useState } from \"react\";\nimport { SocketIOContext } from \"./context\";\n\nexport co"
  },
  {
    "path": "packages/use-socketio/src/index.tsx",
    "chars": 80,
    "preview": "export * from \"./context\";\nexport * from \"./provider\";\nexport * from \"./hooks\";\n"
  },
  {
    "path": "packages/use-socketio/src/provider.tsx",
    "chars": 649,
    "preview": "import * as React from \"react\";\nimport io from \"socket.io-client\";\nimport { SocketIOContext } from \"./context\";\n\nexport "
  },
  {
    "path": "packages/use-socketio/tsconfig.json",
    "chars": 261,
    "preview": "{\n  \"compilerOptions\": {\n    \"declaration\": true,\n    \"esModuleInterop\": true,\n    \"jsx\": \"react\",\n    \"module\": \"common"
  },
  {
    "path": "packages/use-socketio/tslint.json",
    "chars": 159,
    "preview": "{\n  \"extends\": [\n    \"tslint:latest\",\n    \"tslint-plugin-prettier\",\n    \"tslint-config-prettier\"\n  ],\n  \"jsRules\": {},\n "
  },
  {
    "path": "packages/use-websockets/.npmignore",
    "chars": 44,
    "preview": "example\ncypress\nsrc\nnode_modules\ndist\n.cache"
  },
  {
    "path": "packages/use-websockets/README.md",
    "chars": 1593,
    "preview": "Use [Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) with React, in hooks (React v16.8+).\n\n#"
  },
  {
    "path": "packages/use-websockets/package.json",
    "chars": 1112,
    "preview": "{\n  \"name\": \"use-websockets\",\n  \"version\": \"2.1.1\",\n  \"description\": \"React hooks for https://developer.mozilla.org/en-U"
  },
  {
    "path": "packages/use-websockets/src/context.ts",
    "chars": 109,
    "preview": "import { createContext } from \"react\";\n\nexport const WebsocketContext = createContext<WebSocket>(undefined);\n"
  },
  {
    "path": "packages/use-websockets/src/hooks.ts",
    "chars": 1170,
    "preview": "import { useContext, useEffect, useRef, useState } from \"react\";\nimport { WebsocketContext } from \"./context\";\n\nexport c"
  },
  {
    "path": "packages/use-websockets/src/index.tsx",
    "chars": 80,
    "preview": "export * from \"./context\";\nexport * from \"./provider\";\nexport * from \"./hooks\";\n"
  },
  {
    "path": "packages/use-websockets/src/provider.tsx",
    "chars": 872,
    "preview": "import * as React from \"react\";\nimport { WebsocketContext } from \"./context\";\n\nexport interface IWebSocketProviderProps "
  },
  {
    "path": "packages/use-websockets/tsconfig.json",
    "chars": 261,
    "preview": "{\n  \"compilerOptions\": {\n    \"declaration\": true,\n    \"esModuleInterop\": true,\n    \"jsx\": \"react\",\n    \"module\": \"common"
  },
  {
    "path": "packages/use-websockets/tslint.json",
    "chars": 159,
    "preview": "{\n  \"extends\": [\n    \"tslint:latest\",\n    \"tslint-plugin-prettier\",\n    \"tslint-config-prettier\"\n  ],\n  \"jsRules\": {},\n "
  }
]

About this extraction

This page contains the full source code of the mfrachet/use-socketio GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 55 files (38.3 KB), approximately 11.8k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!