nothing-innerstorage 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.MD +91 -0
- package/index.d.ts +46 -0
- package/index.ts +101 -0
- package/package.json +12 -0
package/Readme.MD
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# nothing-innerstorage
|
|
2
|
+
|
|
3
|
+
Persists WhatsApp Web's `localStorage` to disk on every write, and re-injects it before WAWeb JS runs on the next restart — so your session survives process restarts without re-scanning the QR code.
|
|
4
|
+
|
|
5
|
+
The C++ side (`PiggyInnerStorage`) handles all timing. This package is a thin JS wrapper.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install nothing-innerstorage
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
const piggy = require('nothing-browser').default;
|
|
21
|
+
const innerstorage = require('nothing-innerstorage');
|
|
22
|
+
|
|
23
|
+
await piggy.launch({ mode: 'tab', binary: 'headless' });
|
|
24
|
+
await piggy.register('whatsapp', 'https://web.whatsapp.com', { single: true });
|
|
25
|
+
|
|
26
|
+
await piggy.extend(
|
|
27
|
+
innerstorage({ path: './wa-storage.json' })
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
piggy.whatsapp.on('storage:loaded', (d) =>
|
|
31
|
+
console.log(`Session restored: ${d.keys} keys`)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
piggy.whatsapp.on('storage:saved', (d) =>
|
|
35
|
+
console.log(`Session saved: ${d.keys} keys`)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
await piggy.whatsapp.navigate();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Options
|
|
44
|
+
|
|
45
|
+
| Option | Type | Default | Description |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| `path` | `string` | `'./wa-storage.json'` | Where to persist the localStorage snapshot |
|
|
48
|
+
| `onLoaded` | `function` | — | Called when C++ restores a session into the page |
|
|
49
|
+
| `onSaved` | `function` | — | Called when C++ snapshots localStorage to disk |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Events
|
|
54
|
+
|
|
55
|
+
Listen via `site.on(event, handler)`:
|
|
56
|
+
|
|
57
|
+
| Event | Data | When |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `storage:loaded` | `{ tabId, keys }` | Every page load — C++ injected saved keys |
|
|
60
|
+
| `storage:saved` | `{ tabId, keys }` | Every localStorage write — C++ saved snapshot |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## API (`site.storage`)
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
// Read one key from the live page localStorage
|
|
68
|
+
const val = await piggy.whatsapp.storage.get('wa-secret-bundle');
|
|
69
|
+
|
|
70
|
+
// Dump all keys from the live page localStorage
|
|
71
|
+
const all = await piggy.whatsapp.storage.dump();
|
|
72
|
+
|
|
73
|
+
// Wipe localStorage in-page AND delete the snapshot file (forces new QR)
|
|
74
|
+
await piggy.whatsapp.storage.clear();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## How it works
|
|
80
|
+
|
|
81
|
+
- C++ hooks `loadFinished` → injects saved snapshot into `localStorage` before WAWeb reads it
|
|
82
|
+
- C++ installs a JS hook that intercepts every `localStorage.setItem/removeItem/clear` call
|
|
83
|
+
- On each change, C++ snapshots the full localStorage and writes it to the file at `path`
|
|
84
|
+
- On restart, snapshot is re-injected — WAWeb sees its session as intact
|
|
85
|
+
|
|
86
|
+
## Notes
|
|
87
|
+
|
|
88
|
+
- Do **not** call `session.reload()` after installing this plugin — it uses older timing and will conflict
|
|
89
|
+
- To force a fresh QR scan: call `site.storage.clear()` before navigating
|
|
90
|
+
- This plugin was made upon request and need report any issues found
|
|
91
|
+
-This plugin is tailord specificaly for whatsap sessions you can use it on other sites but no guarantee of working and that is not a bug sonner or later nothing-storage plugin will be released to solve that
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface InnerStorageOptions {
|
|
2
|
+
/** Path where localStorage is persisted to disk. Default: './wa-storage.json' */
|
|
3
|
+
path?: string;
|
|
4
|
+
/** Called when C++ restores a saved session into the page (fires on every page load). */
|
|
5
|
+
onLoaded?: (data: { tabId: string; keys: number }) => void;
|
|
6
|
+
/** Called when C++ snapshots localStorage to disk (fires on every localStorage write). */
|
|
7
|
+
onSaved?: (data: { tabId: string; keys: number }) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface StorageAPI {
|
|
11
|
+
/** Read a single key directly from the live localStorage in-page. */
|
|
12
|
+
get(key: string): Promise<string | null>;
|
|
13
|
+
/** Dump all localStorage keys from the live page. */
|
|
14
|
+
dump(): Promise<Record<string, string>>;
|
|
15
|
+
/**
|
|
16
|
+
* Wipe localStorage in-page AND delete the persisted snapshot file.
|
|
17
|
+
* Forces a fresh QR scan on the next restart.
|
|
18
|
+
*/
|
|
19
|
+
clear(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* nothing-innerstorage plugin factory.
|
|
24
|
+
*
|
|
25
|
+
* Returns an installer function. Pass it to `piggy.extend()` or call it manually:
|
|
26
|
+
*
|
|
27
|
+
* ```js
|
|
28
|
+
* // via extend (recommended)
|
|
29
|
+
* await piggy.extend(innerstorage({ path: './wa-storage.json' }));
|
|
30
|
+
*
|
|
31
|
+
* // manually
|
|
32
|
+
* await innerstorage({ path: './wa-storage.json' })(piggy.mysite);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare function innerstorage(opts?: InnerStorageOptions): (site: any) => Promise<any>;
|
|
36
|
+
|
|
37
|
+
export default innerstorage;
|
|
38
|
+
export = innerstorage;
|
|
39
|
+
|
|
40
|
+
// Augment the site object type produced by nothing-browser
|
|
41
|
+
declare module 'nothing-browser' {
|
|
42
|
+
interface PiggySite {
|
|
43
|
+
/** localStorage persistence API — added by nothing-innerstorage */
|
|
44
|
+
storage: StorageAPI;
|
|
45
|
+
}
|
|
46
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// nothing-innerstorage
|
|
4
|
+
// Wraps the C++ PiggyInnerStorage plugin already compiled into the binary.
|
|
5
|
+
// Persists WhatsApp Web's localStorage to disk on every write,
|
|
6
|
+
// and re-injects it before WAWeb JS runs on the next restart.
|
|
7
|
+
//
|
|
8
|
+
// C++ events this listens for:
|
|
9
|
+
// storage:loaded { tabId, keys } — session restored into page
|
|
10
|
+
// storage:saved { tabId, keys } — snapshot written to disk
|
|
11
|
+
//
|
|
12
|
+
// C++ commands this sends:
|
|
13
|
+
// storage.get { key } → string | null
|
|
14
|
+
// storage.dump {} → { key: value, ... }
|
|
15
|
+
// storage.clear {} → "storage cleared"
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {object} opts
|
|
19
|
+
* @param {string} [opts.path='./wa-storage.json'] Path where localStorage is persisted.
|
|
20
|
+
* @param {function} [opts.onLoaded] Called when C++ restores a session.
|
|
21
|
+
* @param {function} [opts.onSaved] Called when C++ snapshots localStorage.
|
|
22
|
+
* @returns {function} Plugin installer — pass to piggy.extend() or call manually.
|
|
23
|
+
*/
|
|
24
|
+
module.exports = function innerstorage(opts) {
|
|
25
|
+
opts = opts || {};
|
|
26
|
+
|
|
27
|
+
const storagePath = opts.path || './wa-storage.json';
|
|
28
|
+
|
|
29
|
+
return async function install(site) {
|
|
30
|
+
if (!site || typeof site.on !== 'function' || typeof site.evaluate !== 'function') {
|
|
31
|
+
throw new Error(
|
|
32
|
+
'[nothing-innerstorage] install() received an invalid site object. ' +
|
|
33
|
+
'Make sure you registered the site with { single: true } and called piggy.extend() after piggy.register().'
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ── Event listeners ──────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
site.on('storage:loaded', function(data) {
|
|
40
|
+
if (typeof opts.onLoaded === 'function') opts.onLoaded(data);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
site.on('storage:saved', function(data) {
|
|
44
|
+
if (typeof opts.onSaved === 'function') opts.onSaved(data);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// ── Attach API to site ───────────────────────────────────────────────────
|
|
48
|
+
// The C++ side already handles injection timing (after loadFinished) and
|
|
49
|
+
// snapshotting (on every localStorage write via the installed JS hook).
|
|
50
|
+
// These commands let you read/inspect the persisted state from Node if needed.
|
|
51
|
+
|
|
52
|
+
site.storage = {
|
|
53
|
+
/**
|
|
54
|
+
* Read a single key from the persisted localStorage snapshot.
|
|
55
|
+
* @param {string} key
|
|
56
|
+
* @returns {Promise<string|null>}
|
|
57
|
+
*/
|
|
58
|
+
get: function(key) {
|
|
59
|
+
if (!key || typeof key !== 'string') {
|
|
60
|
+
return Promise.reject(new Error('[nothing-innerstorage] storage.get() requires a non-empty string key'));
|
|
61
|
+
}
|
|
62
|
+
return site.evaluate(
|
|
63
|
+
`(function(k){ return localStorage.getItem(k); })(${JSON.stringify(key)})`
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Dump the entire persisted localStorage snapshot from disk.
|
|
69
|
+
* @returns {Promise<Record<string, string>>}
|
|
70
|
+
*/
|
|
71
|
+
dump: function() {
|
|
72
|
+
return site.evaluate(
|
|
73
|
+
`(function(){
|
|
74
|
+
var out = {};
|
|
75
|
+
for (var i = 0; i < localStorage.length; i++) {
|
|
76
|
+
var k = localStorage.key(i);
|
|
77
|
+
out[k] = localStorage.getItem(k);
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
})()`
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Wipe the persisted snapshot from disk AND clear localStorage in-page.
|
|
86
|
+
* Use this to force a fresh QR scan on next boot.
|
|
87
|
+
* @returns {Promise<void>}
|
|
88
|
+
*/
|
|
89
|
+
clear: function() {
|
|
90
|
+
return site.evaluate(
|
|
91
|
+
`(function(){ localStorage.clear(); return 'cleared'; })()`
|
|
92
|
+
).then(function() {
|
|
93
|
+
var fs = require('fs');
|
|
94
|
+
try { fs.unlinkSync(storagePath); } catch (_) { /* file may not exist yet */ }
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return site;
|
|
100
|
+
};
|
|
101
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nothing-innerstorage",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "nothing-browser plugin — persists WhatsApp Web localStorage to disk via the C++ PiggyInnerStorage engine",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": ["nothing-browser", "piggy", "whatsapp", "localStorage", "session", "plugin"],
|
|
9
|
+
"peerDependencies": {
|
|
10
|
+
"nothing-browser": "*"
|
|
11
|
+
}
|
|
12
|
+
}
|