Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hanzhixing committed Mar 22, 2023
0 parents commit cd8242a
Show file tree
Hide file tree
Showing 19 changed files with 794 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
>0.2%
not dead
not op_mini all
17 changes: 17 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# General settings for whole project
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_size = 2
14 changes: 14 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
extends: [
'airbnb-base',
'airbnb-typescript/base',
],
parserOptions: {
project: './tsconfig.json',
},
rules: {
'object-curly-newline': ['error', {'multiline': true }],
'@typescript-eslint/indent': ['error', 4],
'@typescript-eslint/object-curly-spacing': ['error', 'never'],
},
};
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store

node_modules/
dist/
package-lock.json
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
registry=https://registry.npmmirror.com
186 changes: 186 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# msgio

If you are familiar with `socket.io`, you already know how to use this package.

`socket.io` is based on WebSocket.

`msgio` is based on postMessage.


## Install

### npm

```js
npm install --save msgio
```

### <script>

```js
<script src="//<path to msgio>/msgio.min.js"></script>
<script>
console.log(window.msgio); // Iframe, Guest
// For detail usage, see below...
</script>
```

## Usage

### Iframe

#### In your Main App
```js
import {Iframe} from 'msgio';

const iframe = document.getElementById('my-iframe');

const onLoad = e => {
const io = new Iframe(e.target);

io.on('connect', socket => {
// listening some events from the guest
socket.on('my_custom_event', data => {
// data: {x: 1, y: 2}
// any code
});

// emit events to the guest
socket.emit('greeting', 'hello world!');

// expose functions to the guest
socket.func('my_sync_fn', (a1, a2, ...rest) => {
// a1: 1
// a2: 2
// rest: 3, 4, 5
// any code
// you can throw as usual!
});

// you can expose aysnc functions too.
socket.func('my_async_fn', (a1, a2, ...rest) => {
// a1: 'a'
// a2: 'b'
// rest: 'c', 'd', 'e'
return new Promise((resolve, reject) => {
// any code
});
});

// call some functions the guest provides.
socket.call('hi', 'guest', '!')
.then(result => {
// as you call the 'hi' function with args 'guest' and '!'
// the resule may be 'hello host!', who knows!
// any code
})
.catch(error => {
// the guest may throw error to you
});
});
};

iframe.addEventListener('load', onLoad);
```

#### In your Iframe
```js
import {Guest} from 'msgio';

// You must provide the host's origin. It's all.
const io = new Guest({host: 'http://localhost:8080'});

// Like in your main app
io.on('connect', socket => {
// the host will use this to set the <iframe>'s width and height.
io.resize({width: 400, height: 600});

// listening some events from the host
socket.on('greeting', data => {
// data: 'hello world!'
// any code
});

// emit events to the guest
socket.emit('my_custom_event', {x: 1, y: 2});

// call functions from the host.
socket.call('my_sync_fn', 1, 2, 3, 4, 5)
.then(result => {
// any code
})
.catch(error => {
// catch the error
});

socket.call('my_async_fn', 'a', 'b', 'c', 'd', 'e')
.then(result => {
// any code
})
.catch(error => {
// catch the error
});

socket.func('hi', (a1, a2, a3) => {
// a1: 'guest'
// a2: '!'
// a3: undefined
// any code
// return 'hello host!'
});
});
```

### Tab
Not implemented yet!

### Web Worker
Not implemented yet!

## API

### Iframe API

#### constructor

> constructor(dom: HTMLIFrameElement)
The dom provied must be a iframe node.

#### on

> on: ('connect', callback: (socket: Socket) => void) => void
### Guest API

#### constructor

> constructor(option: {host:string})
Pass the origin string. eg: http://example.com:8080

#### on

> on: ('connect', callback: (socket: Socket) => void) => void
#### resize

> resize: (size: {width: number, height: number}) => void;
### Socket API

#### on

> on: (event: string, callback: (...args: any) => void) => void
#### emit

> emit: (event: string, payload: any) => void
#### func

> func: (fname: string, callback: (...args: any) => any) => void
#### call

> call: (fname: string, ...args: any) => Promise&lt;any&gt;
6 changes: 6 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
],
};
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
clearMocks: true,
collectCoverage: true,
coverageDirectory: 'coverage',
testEnvironment: 'jsdom',
};
45 changes: 45 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "msgio",
"version": "0.1.0",
"description": "'postMessage' based communication library.",
"license": "MIT",
"author": "Zhixing Han <zhixing.han.0409@gmail.com>",
"files": [
"dist",
"src"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "npm run clean && npm run build:cjs && npm run build:umd",
"build:cjs": "tsc",
"build:umd": "npx rollup -c --bundleConfigAsCjs",
"clean": "rimraf dist",
"test": "jest"
},
"dependencies": {
"nanoevents": "^7.0.1",
"nanoid": "^4.0.1"
},
"devDependencies": {
"@babel/cli": "^7.21.0",
"@babel/core": "^7.21.3",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.21.0",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-terser": "^0.4.0",
"@tsconfig/recommended": "^1.0.2",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"babel-jest": "^29.5.0",
"eslint": "^8.36.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-plugin-import": "^2.27.5",
"jest": "^29.5.0",
"rimraf": "^4.4.0",
"rollup": "^3.19.1",
"typescript": "^5.0.2"
}
}
26 changes: 26 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import resolve from '@rollup/plugin-node-resolve';
import {babel} from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';

const extensions = ['.ts'];

export default {
input: 'src/index.ts',
output: {
name: 'msgio',
file: 'dist/msgio.min.js',
format: 'umd',
sourcemap: true,
},
plugins: [
resolve({
extensions,
browser: true,
}),
babel({
extensions,
babelHelpers: 'bundled',
}),
terser(),
],
};
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* eslint import/prefer-default-export: 0 */
export const MIME_TYPE = 'application/msgio+json';
51 changes: 51 additions & 0 deletions src/endpoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {createNanoEvents} from 'nanoevents';
import {EndpointEvent, EndpointEventType, Receiver} from './types';
import type Socket from './socket';
import {MIME_TYPE} from './constants';

class Endpoint {
emitter = createNanoEvents();

origin = window.location.origin;

socketId = 'none';

receiver: Receiver;

constructor(receiver: Receiver) {
this.receiver = receiver;
}

sendPacket = (type: EndpointEventType, body: any) => {
this.receiver.target.postMessage({
mime: MIME_TYPE,
type,
socket: type === 'CONNECT' ? this.socketId : undefined,
body,
}, this.receiver.origin);
};

isValidEvent = (e: EndpointEvent) => {
const {origin, data: {mime, type, socket}} = e;

if (origin !== this.receiver.origin) {
return false;
}

if (mime !== MIME_TYPE) {
return false;
}

if (type !== 'CONNECT' && socket !== this.socketId) {
return false;
}

return true;
};

on = (event: 'connect', fn: (socket: Socket) => void) => {
this.emitter.on(event, fn);
};
}

export default Endpoint;
Loading

0 comments on commit cd8242a

Please sign in to comment.