memcache 0.2.0 → 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/.github/ISSUE_TEMPLATE/bug_report.md +14 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +6 -0
- package/.github/workflows/code-coverage.yaml +41 -0
- package/.github/workflows/codeql.yaml +75 -0
- package/.github/workflows/release.yaml +41 -0
- package/.github/workflows/tests.yaml +40 -0
- package/.nvmrc +1 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +27 -0
- package/LICENSE +21 -0
- package/README.md +369 -71
- package/SECURITY.md +3 -0
- package/biome.json +35 -0
- package/dist/index.cjs +1502 -0
- package/dist/index.d.cts +501 -0
- package/dist/index.d.ts +501 -0
- package/dist/index.js +1475 -0
- package/docker-compose.yml +24 -0
- package/package.json +38 -17
- package/pnpm-workspace.yaml +2 -0
- package/site/favicon.ico +0 -0
- package/site/logo.ai +7222 -37
- package/site/logo.png +0 -0
- package/site/logo.svg +7 -0
- package/site/logo.webp +0 -0
- package/site/logo_medium.png +0 -0
- package/site/logo_small.png +0 -0
- package/src/index.ts +1130 -0
- package/src/ketama.ts +449 -0
- package/src/node.ts +488 -0
- package/test/index.test.ts +2734 -0
- package/test/ketama.test.ts +526 -0
- package/test/memcache-node-instances.test.ts +102 -0
- package/test/node.test.ts +809 -0
- package/tsconfig.json +29 -0
- package/vitest.config.ts +16 -0
- package/.gitignore +0 -2
- package/Makefile +0 -13
- package/example.js +0 -68
- package/index.js +0 -1
- package/lib/memcache.js +0 -344
- package/test/test-memcache.js +0 -238
package/README.md
CHANGED
|
@@ -1,106 +1,404 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
[<img src="./site/logo_medium.png" alt="Memcache Logo" align="center">](https://memcachejs.org)
|
|
2
|
+
|
|
3
|
+
[](https://codecov.io/gh/jaredwray/memcache)
|
|
4
|
+
[](https://github.com/jaredwray/memcache/actions/workflows/tests.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/memcache)
|
|
6
|
+
[](https://www.npmjs.com/package/memcache)
|
|
7
|
+
[](https://github.com/jaredwray/memcache/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
# Memcache
|
|
10
|
+
Nodejs Memcache Client
|
|
11
|
+
|
|
12
|
+
# Table of Contents
|
|
13
|
+
|
|
14
|
+
- [Getting Started](#getting-started)
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Basic Usage](#basic-usage)
|
|
17
|
+
- [Custom Connection](#custom-connection)
|
|
18
|
+
- [API](#api)
|
|
19
|
+
- [Constructor](#constructor)
|
|
20
|
+
- [Properties](#properties)
|
|
21
|
+
- [Connection Management](#connection-management)
|
|
22
|
+
- [Node Management](#node-management)
|
|
23
|
+
- [Data Storage Operations](#data-storage-operations)
|
|
24
|
+
- [String Modification Operations](#string-modification-operations)
|
|
25
|
+
- [Deletion & Expiration](#deletion--expiration)
|
|
26
|
+
- [Numeric Operations](#numeric-operations)
|
|
27
|
+
- [Server Management & Statistics](#server-management--statistics)
|
|
28
|
+
- [Validation](#validation)
|
|
29
|
+
- [Helper Functions](#helper-functions)
|
|
30
|
+
- [Hooks and Events](#hooks-and-events)
|
|
31
|
+
- [Events](#events)
|
|
32
|
+
- [Available Events](#available-events)
|
|
33
|
+
- [Hooks](#hooks)
|
|
34
|
+
- [Available Hooks](#available-hooks)
|
|
35
|
+
- [get(key)](#getkey)
|
|
36
|
+
- [set(key, value, exptime?, flags?)](#setkey-value-exptime-flags)
|
|
37
|
+
- [gets(keys[])](#getskeys)
|
|
38
|
+
- [add(key, value, exptime?, flags?)](#addkey-value-exptime-flags)
|
|
39
|
+
- [replace(key, value, exptime?, flags?)](#replacekey-value-exptime-flags)
|
|
40
|
+
- [append(key, value)](#appendkey-value)
|
|
41
|
+
- [prepend(key, value)](#prependkey-value)
|
|
42
|
+
- [delete(key)](#deletekey)
|
|
43
|
+
- [incr(key, value?)](#incrkey-value)
|
|
44
|
+
- [decr(key, value?)](#decrkey-value)
|
|
45
|
+
- [touch(key, exptime)](#touchkey-exptime)
|
|
46
|
+
- [Hook Examples](#hook-examples)
|
|
47
|
+
- [Contributing](#contributing)
|
|
48
|
+
- [License and Copyright](#license-and-copyright)
|
|
3
49
|
|
|
4
|
-
|
|
50
|
+
# Getting Started
|
|
5
51
|
|
|
52
|
+
## Installation
|
|
6
53
|
|
|
7
|
-
|
|
8
|
-
|
|
54
|
+
```bash
|
|
55
|
+
npm install memcache
|
|
56
|
+
```
|
|
9
57
|
|
|
10
|
-
|
|
11
|
-
then run <code>make test</code>.
|
|
58
|
+
or with pnpm:
|
|
12
59
|
|
|
13
|
-
|
|
14
|
-
|
|
60
|
+
```bash
|
|
61
|
+
pnpm add memcache
|
|
62
|
+
```
|
|
15
63
|
|
|
64
|
+
## Basic Usage
|
|
16
65
|
|
|
17
|
-
|
|
18
|
-
|
|
66
|
+
```javascript
|
|
67
|
+
import { Memcache } from 'memcache';
|
|
19
68
|
|
|
20
|
-
Create a
|
|
21
|
-
|
|
22
|
-
They have sensible defaults.
|
|
69
|
+
// Create a new client
|
|
70
|
+
const client = new Memcache();
|
|
23
71
|
|
|
24
|
-
|
|
72
|
+
// Set a value
|
|
73
|
+
await client.set('mykey', 'Hello, Memcache!');
|
|
25
74
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
75
|
+
// Get a value
|
|
76
|
+
const value = await client.get('mykey');
|
|
77
|
+
console.log(value); // ['Hello, Memcache!']
|
|
29
78
|
|
|
30
|
-
|
|
79
|
+
// Delete a value
|
|
80
|
+
await client.delete('mykey');
|
|
31
81
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
82
|
+
// Close the connection
|
|
83
|
+
await client.quit();
|
|
84
|
+
```
|
|
35
85
|
|
|
36
|
-
|
|
37
|
-
// no arguments - connection has been closed
|
|
38
|
-
});
|
|
86
|
+
# API
|
|
39
87
|
|
|
40
|
-
|
|
41
|
-
// no arguments - socket timed out
|
|
42
|
-
});
|
|
88
|
+
## Constructor
|
|
43
89
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
90
|
+
```typescript
|
|
91
|
+
new Memcache(options?: MemcacheOptions)
|
|
92
|
+
```
|
|
47
93
|
|
|
48
|
-
|
|
94
|
+
Creates a new Memcache client instance.
|
|
49
95
|
|
|
50
|
-
|
|
96
|
+
### Options
|
|
51
97
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
98
|
+
- `nodes?: (string | MemcacheNode)[]` - Array of node URIs or MemcacheNode instances
|
|
99
|
+
- Examples: `["localhost:11211", "memcache://192.168.1.100:11212"]`
|
|
100
|
+
- `timeout?: number` - Operation timeout in milliseconds (default: 5000)
|
|
101
|
+
- `keepAlive?: boolean` - Keep connection alive (default: true)
|
|
102
|
+
- `keepAliveDelay?: number` - Keep alive delay in milliseconds (default: 1000)
|
|
103
|
+
- `hash?: HashProvider` - Hash provider for consistent hashing (default: KetamaHash)
|
|
55
104
|
|
|
56
|
-
|
|
105
|
+
## Properties
|
|
57
106
|
|
|
58
|
-
|
|
107
|
+
### `nodes: MemcacheNode[]` (readonly)
|
|
108
|
+
Returns the list of all MemcacheNode instances in the cluster.
|
|
59
109
|
|
|
60
|
-
|
|
61
|
-
|
|
110
|
+
### `nodeIds: string[]` (readonly)
|
|
111
|
+
Returns the list of node IDs (e.g., `["localhost:11211", "127.0.0.1:11212"]`).
|
|
62
112
|
|
|
63
|
-
|
|
113
|
+
### `hash: HashProvider`
|
|
114
|
+
Get or set the hash provider used for consistent hashing distribution.
|
|
64
115
|
|
|
65
|
-
|
|
116
|
+
### `timeout: number`
|
|
117
|
+
Get or set the timeout for operations in milliseconds (default: 5000).
|
|
66
118
|
|
|
67
|
-
|
|
68
|
-
|
|
119
|
+
### `keepAlive: boolean`
|
|
120
|
+
Get or set the keepAlive setting. Updates all existing nodes. Requires `reconnect()` to apply changes.
|
|
69
121
|
|
|
70
|
-
|
|
122
|
+
### `keepAliveDelay: number`
|
|
123
|
+
Get or set the keep alive delay in milliseconds. Updates all existing nodes. Requires `reconnect()` to apply changes.
|
|
71
124
|
|
|
72
|
-
|
|
73
|
-
});
|
|
125
|
+
## Connection Management
|
|
74
126
|
|
|
127
|
+
### `connect(nodeId?: string): Promise<void>`
|
|
128
|
+
Connect to all Memcache servers or a specific node.
|
|
75
129
|
|
|
76
|
-
|
|
130
|
+
### `disconnect(): Promise<void>`
|
|
131
|
+
Disconnect all connections.
|
|
77
132
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
client.set(key, value, callback, lifetime, flags);
|
|
81
|
-
client.add(key, value, callback, lifetime, flags);
|
|
82
|
-
client.replace(key, value, callback, lifetime, flags);
|
|
83
|
-
client.append(key, value, callback, lifetime, flags);
|
|
84
|
-
client.prepend(key, value, callback, lifetime, flags);
|
|
85
|
-
client.cas(key, value, unique, callback, lifetime, flags);
|
|
133
|
+
### `reconnect(): Promise<void>`
|
|
134
|
+
Reconnect all nodes by disconnecting and connecting them again.
|
|
86
135
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
client.increment('key', value, callback);
|
|
90
|
-
client.decrement('key', value, callback);
|
|
136
|
+
### `quit(): Promise<void>`
|
|
137
|
+
Quit all connections gracefully.
|
|
91
138
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
client.stats(callback);
|
|
95
|
-
client.stats('settings', callback);
|
|
96
|
-
client.stats('items', callback);
|
|
97
|
-
client.stats('mongeese', callback);
|
|
139
|
+
### `isConnected(): boolean`
|
|
140
|
+
Check if any node is connected to a Memcache server.
|
|
98
141
|
|
|
99
|
-
|
|
142
|
+
## Node Management
|
|
100
143
|
|
|
101
|
-
|
|
144
|
+
### `getNodes(): MemcacheNode[]`
|
|
145
|
+
Get an array of all MemcacheNode instances.
|
|
102
146
|
|
|
103
|
-
|
|
147
|
+
### `getNode(id: string): MemcacheNode | undefined`
|
|
148
|
+
Get a specific node by its ID (e.g., `"localhost:11211"`).
|
|
104
149
|
|
|
105
|
-
|
|
106
|
-
|
|
150
|
+
### `addNode(uri: string | MemcacheNode, weight?: number): Promise<void>`
|
|
151
|
+
Add a new node to the cluster. Throws error if node already exists.
|
|
152
|
+
|
|
153
|
+
### `removeNode(uri: string): Promise<void>`
|
|
154
|
+
Remove a node from the cluster.
|
|
155
|
+
|
|
156
|
+
### `getNodesByKey(key: string): Promise<MemcacheNode[]>`
|
|
157
|
+
Get the nodes for a given key using consistent hashing. Automatically connects to nodes if not already connected.
|
|
158
|
+
|
|
159
|
+
### `parseUri(uri: string): { host: string; port: number }`
|
|
160
|
+
Parse a URI string into host and port. Supports formats:
|
|
161
|
+
- Simple: `"localhost:11211"` or `"localhost"`
|
|
162
|
+
- Protocol: `"memcache://localhost:11211"`, `"tcp://localhost:11211"`
|
|
163
|
+
- IPv6: `"[::1]:11211"` or `"memcache://[2001:db8::1]:11212"`
|
|
164
|
+
- Unix socket: `"/var/run/memcached.sock"` or `"unix:///var/run/memcached.sock"`
|
|
165
|
+
|
|
166
|
+
## Data Storage Operations
|
|
167
|
+
|
|
168
|
+
### `get(key: string): Promise<string | undefined>`
|
|
169
|
+
Get a value from the Memcache server. Returns the first successful result from replica nodes.
|
|
170
|
+
|
|
171
|
+
### `gets(keys: string[]): Promise<Map<string, string>>`
|
|
172
|
+
Get multiple values from the Memcache server. Returns a Map with keys to values.
|
|
173
|
+
|
|
174
|
+
### `set(key: string, value: string, exptime?: number, flags?: number): Promise<boolean>`
|
|
175
|
+
Set a value in the Memcache server. Returns true only if all replica nodes succeed.
|
|
176
|
+
- `exptime` - Expiration time in seconds (default: 0 = never expire)
|
|
177
|
+
- `flags` - Flags/metadata (default: 0)
|
|
178
|
+
|
|
179
|
+
### `add(key: string, value: string, exptime?: number, flags?: number): Promise<boolean>`
|
|
180
|
+
Add a value (only if key doesn't exist). Returns true only if all replica nodes succeed.
|
|
181
|
+
|
|
182
|
+
### `replace(key: string, value: string, exptime?: number, flags?: number): Promise<boolean>`
|
|
183
|
+
Replace a value (only if key exists). Returns true only if all replica nodes succeed.
|
|
184
|
+
|
|
185
|
+
### `cas(key: string, value: string, casToken: string, exptime?: number, flags?: number): Promise<boolean>`
|
|
186
|
+
Check-And-Set: Store a value only if it hasn't been modified since last fetch. Returns true only if all replica nodes succeed.
|
|
187
|
+
|
|
188
|
+
## String Modification Operations
|
|
189
|
+
|
|
190
|
+
### `append(key: string, value: string): Promise<boolean>`
|
|
191
|
+
Append a value to an existing key. Returns true only if all replica nodes succeed.
|
|
192
|
+
|
|
193
|
+
### `prepend(key: string, value: string): Promise<boolean>`
|
|
194
|
+
Prepend a value to an existing key. Returns true only if all replica nodes succeed.
|
|
195
|
+
|
|
196
|
+
## Deletion & Expiration
|
|
197
|
+
|
|
198
|
+
### `delete(key: string): Promise<boolean>`
|
|
199
|
+
Delete a value from the Memcache server. Returns true only if all replica nodes succeed.
|
|
200
|
+
|
|
201
|
+
### `touch(key: string, exptime: number): Promise<boolean>`
|
|
202
|
+
Update expiration time without retrieving value. Returns true only if all replica nodes succeed.
|
|
203
|
+
|
|
204
|
+
## Numeric Operations
|
|
205
|
+
|
|
206
|
+
### `incr(key: string, value?: number): Promise<number | undefined>`
|
|
207
|
+
Increment a value. Returns the new value or undefined on failure.
|
|
208
|
+
- `value` - Amount to increment (default: 1)
|
|
209
|
+
|
|
210
|
+
### `decr(key: string, value?: number): Promise<number | undefined>`
|
|
211
|
+
Decrement a value. Returns the new value or undefined on failure.
|
|
212
|
+
- `value` - Amount to decrement (default: 1)
|
|
213
|
+
|
|
214
|
+
## Server Management & Statistics
|
|
215
|
+
|
|
216
|
+
### `flush(delay?: number): Promise<boolean>`
|
|
217
|
+
Flush all values from all Memcache servers. Returns true if all nodes successfully flushed.
|
|
218
|
+
- `delay` - Optional delay in seconds before flushing
|
|
219
|
+
|
|
220
|
+
### `stats(type?: string): Promise<Map<string, MemcacheStats>>`
|
|
221
|
+
Get statistics from all Memcache servers. Returns a Map of node IDs to their stats.
|
|
222
|
+
|
|
223
|
+
### `version(): Promise<Map<string, string>>`
|
|
224
|
+
Get the Memcache server version from all nodes. Returns a Map of node IDs to version strings.
|
|
225
|
+
|
|
226
|
+
## Validation
|
|
227
|
+
|
|
228
|
+
### `validateKey(key: string): void`
|
|
229
|
+
Validates a Memcache key according to protocol requirements. Throws error if:
|
|
230
|
+
- Key is empty
|
|
231
|
+
- Key exceeds 250 characters
|
|
232
|
+
- Key contains spaces, newlines, or null characters
|
|
233
|
+
|
|
234
|
+
## Helper Functions
|
|
235
|
+
|
|
236
|
+
### `createNode(host: string, port: number, options?: MemcacheNodeOptions): MemcacheNode`
|
|
237
|
+
Factory function to create a new MemcacheNode instance.
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
import { createNode } from 'memcache';
|
|
241
|
+
|
|
242
|
+
const node = createNode('localhost', 11211, {
|
|
243
|
+
timeout: 5000,
|
|
244
|
+
keepAlive: true,
|
|
245
|
+
weight: 1
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
# Hooks and Events
|
|
250
|
+
|
|
251
|
+
The Memcache client extends [Hookified](https://github.com/jaredwray/hookified) to provide powerful hooks and events for monitoring and customizing behavior.
|
|
252
|
+
|
|
253
|
+
## Events
|
|
254
|
+
|
|
255
|
+
The client emits various events during operations that you can listen to:
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
const client = new Memcache();
|
|
259
|
+
|
|
260
|
+
// Connection events
|
|
261
|
+
client.on('connect', () => {
|
|
262
|
+
console.log('Connected to Memcache server');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
client.on('close', () => {
|
|
266
|
+
console.log('Connection closed');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
client.on('error', (error) => {
|
|
270
|
+
console.error('Error:', error);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
client.on('timeout', () => {
|
|
274
|
+
console.log('Connection timeout');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Cache hit/miss events
|
|
278
|
+
client.on('hit', (key, value) => {
|
|
279
|
+
console.log(`Cache hit for key: ${key}`);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
client.on('miss', (key) => {
|
|
283
|
+
console.log(`Cache miss for key: ${key}`);
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Available Events
|
|
288
|
+
|
|
289
|
+
- `connect` - Emitted when connection to Memcache server is established
|
|
290
|
+
- `close` - Emitted when connection is closed
|
|
291
|
+
- `error` - Emitted when an error occurs
|
|
292
|
+
- `timeout` - Emitted when a connection timeout occurs
|
|
293
|
+
- `hit` - Emitted when a key is found in cache (includes key and value)
|
|
294
|
+
- `miss` - Emitted when a key is not found in cache
|
|
295
|
+
- `quit` - Emitted when quit command is sent
|
|
296
|
+
- `warn` - Emitted for warning messages
|
|
297
|
+
- `info` - Emitted for informational messages
|
|
298
|
+
|
|
299
|
+
## Hooks
|
|
300
|
+
|
|
301
|
+
Hooks allow you to intercept and modify behavior before and after operations. Every operation supports `before` and `after` hooks.
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
const client = new Memcache();
|
|
305
|
+
|
|
306
|
+
// Add a before hook for get operations
|
|
307
|
+
client.onHook('before:get', async ({ key }) => {
|
|
308
|
+
console.log(`Getting key: ${key}`);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Add an after hook for set operations
|
|
312
|
+
client.onHook('after:set', async ({ key, value, success }) => {
|
|
313
|
+
if (success) {
|
|
314
|
+
console.log(`Successfully set ${key}`);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// Hooks can be async and modify behavior
|
|
319
|
+
client.onHook('before:set', async ({ key, value }) => {
|
|
320
|
+
console.log(`About to set ${key} = ${value}`);
|
|
321
|
+
// Perform validation, logging, etc.
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Available Hooks
|
|
326
|
+
|
|
327
|
+
All operations support before and after hooks with specific parameters:
|
|
328
|
+
|
|
329
|
+
## get(key)
|
|
330
|
+
- `before:get` - `{ key }`
|
|
331
|
+
- `after:get` - `{ key, value }` (value is array or undefined)
|
|
332
|
+
|
|
333
|
+
## set(key, value, exptime?, flags?)
|
|
334
|
+
- `before:set` - `{ key, value, exptime, flags }`
|
|
335
|
+
- `after:set` - `{ key, value, exptime, flags, success }`
|
|
336
|
+
|
|
337
|
+
## gets(keys[])
|
|
338
|
+
- `before:gets` - `{ keys }`
|
|
339
|
+
- `after:gets` - `{ keys, values }` (values is a Map)
|
|
340
|
+
|
|
341
|
+
## add(key, value, exptime?, flags?)
|
|
342
|
+
- `before:add` - `{ key, value, exptime, flags }`
|
|
343
|
+
- `after:add` - `{ key, value, exptime, flags, success }`
|
|
344
|
+
|
|
345
|
+
## replace(key, value, exptime?, flags?)
|
|
346
|
+
- `before:replace` - `{ key, value, exptime, flags }`
|
|
347
|
+
- `after:replace` - `{ key, value, exptime, flags, success }`
|
|
348
|
+
|
|
349
|
+
## append(key, value)
|
|
350
|
+
- `before:append` - `{ key, value }`
|
|
351
|
+
- `after:append` - `{ key, value, success }`
|
|
352
|
+
|
|
353
|
+
## prepend(key, value)
|
|
354
|
+
- `before:prepend` - `{ key, value }`
|
|
355
|
+
- `after:prepend` - `{ key, value, success }`
|
|
356
|
+
|
|
357
|
+
## delete(key)
|
|
358
|
+
- `before:delete` - `{ key }`
|
|
359
|
+
- `after:delete` - `{ key, success }`
|
|
360
|
+
|
|
361
|
+
## incr(key, value?)
|
|
362
|
+
- `before:incr` - `{ key, value }`
|
|
363
|
+
- `after:incr` - `{ key, value, newValue }`
|
|
364
|
+
|
|
365
|
+
## decr(key, value?)
|
|
366
|
+
- `before:decr` - `{ key, value }`
|
|
367
|
+
- `after:decr` - `{ key, value, newValue }`
|
|
368
|
+
|
|
369
|
+
## touch(key, exptime)
|
|
370
|
+
- `before:touch` - `{ key, exptime }`
|
|
371
|
+
- `after:touch` - `{ key, exptime, success }`
|
|
372
|
+
|
|
373
|
+
## Hook Examples
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
const client = new Memcache();
|
|
377
|
+
|
|
378
|
+
// Log all get operations
|
|
379
|
+
client.onHook('before:get', async ({ key }) => {
|
|
380
|
+
console.log(`[GET] Fetching key: ${key}`);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
client.onHook('after:get', async ({ key, value }) => {
|
|
384
|
+
console.log(`[GET] Key: ${key}, Found: ${value !== undefined}`);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Log all set operations with timing
|
|
388
|
+
client.onHook('before:set', async (context) => {
|
|
389
|
+
context.startTime = Date.now();
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
client.onHook('after:set', async (context) => {
|
|
393
|
+
const duration = Date.now() - context.startTime;
|
|
394
|
+
console.log(`[SET] Key: ${context.key}, Success: ${context.success}, Time: ${duration}ms`);
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
# Contributing
|
|
399
|
+
|
|
400
|
+
Please read our [Contributing Guidelines](./CONTRIBUTING.md) and also our [Code of Conduct](./CODE_OF_CONDUCT.md).
|
|
401
|
+
|
|
402
|
+
# License and Copyright
|
|
403
|
+
|
|
404
|
+
[MIT & Copyright (c) Jared Wray](https://github.com/jaredwray/memcache/blob/main/LICENSE)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
We work hard to keep up to date with continual updates to this project. If there are concerns / security related issues please create an issue as soon as possible with how to replicate. If it is urgent please email me@jaredwray.com and I will respond as soon as possible as we take these matters seriously.
|
package/biome.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": false,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": false
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false,
|
|
10
|
+
"includes": ["src/**/*", "test/**/*", "benchmark/**/*"]
|
|
11
|
+
},
|
|
12
|
+
"formatter": {
|
|
13
|
+
"enabled": true,
|
|
14
|
+
"indentStyle": "tab"
|
|
15
|
+
},
|
|
16
|
+
"linter": {
|
|
17
|
+
"enabled": true,
|
|
18
|
+
"rules": {
|
|
19
|
+
"recommended": true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"javascript": {
|
|
23
|
+
"formatter": {
|
|
24
|
+
"quoteStyle": "double"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"assist": {
|
|
28
|
+
"enabled": true,
|
|
29
|
+
"actions": {
|
|
30
|
+
"source": {
|
|
31
|
+
"organizeImports": "on"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|