@gcoredev/proxy-wasm-sdk-as 1.1.0 → 1.2.1-alpha.1
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 +6 -1
- package/assembly/fastedge/env.ts +14 -0
- package/assembly/fastedge/index.ts +4 -0
- package/assembly/fastedge/kvStore.ts +228 -0
- package/assembly/fastedge/secrets.ts +51 -0
- package/assembly/fastedge/utils/index.ts +2 -0
- package/assembly/fastedge/utils/listParser.ts +70 -0
- package/assembly/fastedge/utils/runtime.ts +31 -0
- package/assembly/imports.ts +65 -0
- package/assembly/index.ts +0 -8
- package/assembly/runtime.ts +9 -4
- package/package.json +4 -4
- package/assembly/fastedge.ts +0 -82
package/README.md
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
[](https://github.com/G-Core/proxy-wasm-sdk-as)
|
|
6
6
|
[](https://github.com/G-Core/proxy-wasm-sdk-as/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@gcoredev/proxy-wasm-sdk-as)
|
|
8
|
+
[](https://app.fossa.com/projects/git%2Bgithub.com%2FG-Core%2Fproxy-wasm-sdk-as?ref=badge_shield)
|
|
8
9
|
|
|
9
10
|
This is a friendly fork of https://github.com/Kong/proxy-wasm-assemblyscript-sdk/,
|
|
10
11
|
mantained to address an incompatibility between the AssemblyScript SDK and the Rust SDK,
|
|
11
12
|
|
|
12
|
-
It also
|
|
13
|
+
It also provides FastEdge specific functionality for accessing resources.
|
|
13
14
|
|
|
14
15
|
## How to use this SDK
|
|
15
16
|
|
|
@@ -99,3 +100,7 @@ Please see [Envoy.md](./ENVOY.md)
|
|
|
99
100
|
## Examples
|
|
100
101
|
|
|
101
102
|
For more examples on how to use this `proxy-wasm-sdk-as` please see our [examples repo](https://github.com/G-Core/FastEdge-examples/tree/main/assemblyscript)
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
[](https://app.fossa.com/projects/git%2Bgithub.com%2FG-Core%2Fproxy-wasm-sdk-as?ref=badge_large)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function to get the value for the provided environment variable name.
|
|
3
|
+
* @param {string} name - The name of the environment variable.
|
|
4
|
+
* @returns {string} The value of the environment variable.
|
|
5
|
+
*/
|
|
6
|
+
function getEnvVar(name: string): string {
|
|
7
|
+
const hasKey = process.env.has(name);
|
|
8
|
+
if (hasKey) {
|
|
9
|
+
return process.env.get(name);
|
|
10
|
+
}
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { getEnvVar };
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import * as imports from "../imports";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
globalArrayBufferReference,
|
|
5
|
+
Reference,
|
|
6
|
+
WasmResultValues,
|
|
7
|
+
} from "../runtime";
|
|
8
|
+
import { ItemParser, StringParser, parseBufferToList } from "./utils";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* KvStore provides access to the FastEdge Key-Value store
|
|
12
|
+
*/
|
|
13
|
+
export class KvStore {
|
|
14
|
+
private handle: u32;
|
|
15
|
+
|
|
16
|
+
private constructor(handle: u32) {
|
|
17
|
+
this.handle = handle;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Opens a connection to the specified KV store
|
|
22
|
+
* @param storeName - The name of the KV store to open
|
|
23
|
+
* @returns A new KvStore instance or null if the store cannot be opened
|
|
24
|
+
*/
|
|
25
|
+
static open(storeName: string): KvStore | null {
|
|
26
|
+
const buffer = String.UTF8.encode(storeName);
|
|
27
|
+
const returnHandlerRef = new Reference<u32>();
|
|
28
|
+
|
|
29
|
+
const status = imports.proxy_kv_store_open(
|
|
30
|
+
changetype<usize>(buffer),
|
|
31
|
+
buffer.byteLength,
|
|
32
|
+
returnHandlerRef.ptr() as u32
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (status == WasmResultValues.Ok) {
|
|
36
|
+
return new KvStore(returnHandlerRef.data);
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Retrieves the value associated with the given key from the KV store.
|
|
43
|
+
* @param {string} key The key to retrieve the value for.
|
|
44
|
+
* @returns {ArrayBuffer | null} The value associated with the key, or null if not found.
|
|
45
|
+
*/
|
|
46
|
+
get(key: string): ArrayBuffer | null {
|
|
47
|
+
const buffer = String.UTF8.encode(key);
|
|
48
|
+
const status = imports.proxy_kv_store_get(
|
|
49
|
+
this.getHandle(),
|
|
50
|
+
changetype<usize>(buffer),
|
|
51
|
+
buffer.byteLength,
|
|
52
|
+
globalArrayBufferReference.bufferPtr(),
|
|
53
|
+
globalArrayBufferReference.sizePtr()
|
|
54
|
+
);
|
|
55
|
+
if (status == WasmResultValues.Ok) {
|
|
56
|
+
return globalArrayBufferReference.toArrayBuffer();
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Retrieves all key prefix matches from the KV store.
|
|
63
|
+
* @param {string} pattern The prefix pattern to match keys against. e.g. 'foo*' ( Must include wildcard )
|
|
64
|
+
* @returns {Array<string>} The keys matching the pattern, or empty array if none found.
|
|
65
|
+
*/
|
|
66
|
+
scan(pattern: string): Array<string> {
|
|
67
|
+
const match = String.UTF8.encode(pattern);
|
|
68
|
+
const status = imports.proxy_kv_store_scan(
|
|
69
|
+
this.getHandle(),
|
|
70
|
+
changetype<usize>(match),
|
|
71
|
+
match.byteLength,
|
|
72
|
+
globalArrayBufferReference.bufferPtr(),
|
|
73
|
+
globalArrayBufferReference.sizePtr()
|
|
74
|
+
);
|
|
75
|
+
if (status == WasmResultValues.Ok) {
|
|
76
|
+
return parseBufferToList<string>(
|
|
77
|
+
globalArrayBufferReference.toArrayBuffer(),
|
|
78
|
+
new StringParser()
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return new Array<string>();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Retrieves all the values from ZSet with scores between the given range.
|
|
86
|
+
* @param {string} key The key for the Sorted Set.
|
|
87
|
+
* @param {f64} min The minimum score for the range.
|
|
88
|
+
* @param {f64} max The maximum score for the range.
|
|
89
|
+
* @returns {Array<ValueScoreTuple>} Array of [value, score] tuples within range for the key, or an empty array if none found.
|
|
90
|
+
*/
|
|
91
|
+
zrangeByScore(key: string, min: f64, max: f64): Array<ValueScoreTuple> {
|
|
92
|
+
const keyBuffer = String.UTF8.encode(key);
|
|
93
|
+
const status = imports.proxy_kv_store_zrange_by_score(
|
|
94
|
+
this.getHandle(),
|
|
95
|
+
changetype<usize>(keyBuffer),
|
|
96
|
+
keyBuffer.byteLength,
|
|
97
|
+
min,
|
|
98
|
+
max,
|
|
99
|
+
globalArrayBufferReference.bufferPtr(),
|
|
100
|
+
globalArrayBufferReference.sizePtr()
|
|
101
|
+
);
|
|
102
|
+
if (status == WasmResultValues.Ok) {
|
|
103
|
+
return parseBufferToList<ValueScoreTuple>(
|
|
104
|
+
globalArrayBufferReference.toArrayBuffer(),
|
|
105
|
+
new ValueScoreTupleParser()
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
return new Array<ValueScoreTuple>();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Retrieves all value prefix matches from the KV ZSet.
|
|
113
|
+
* @param {string} key The key for the Sorted Set.
|
|
114
|
+
* @param {string} pattern The prefix pattern to match values against. e.g. 'foo*' ( Must include wildcard )
|
|
115
|
+
* @returns {Array<ValueScoreTuple>} Array of [value, score] tuples which match the prefix pattern, or an empty array if none found.
|
|
116
|
+
*/
|
|
117
|
+
zscan(key: string, pattern: string): Array<ValueScoreTuple> {
|
|
118
|
+
const match = String.UTF8.encode(pattern);
|
|
119
|
+
const keyBuffer = String.UTF8.encode(key);
|
|
120
|
+
const status = imports.proxy_kv_store_zscan(
|
|
121
|
+
this.getHandle(),
|
|
122
|
+
changetype<usize>(keyBuffer),
|
|
123
|
+
keyBuffer.byteLength,
|
|
124
|
+
changetype<usize>(match),
|
|
125
|
+
match.byteLength,
|
|
126
|
+
globalArrayBufferReference.bufferPtr(),
|
|
127
|
+
globalArrayBufferReference.sizePtr()
|
|
128
|
+
);
|
|
129
|
+
if (status == WasmResultValues.Ok) {
|
|
130
|
+
return parseBufferToList<ValueScoreTuple>(
|
|
131
|
+
globalArrayBufferReference.toArrayBuffer(),
|
|
132
|
+
new ValueScoreTupleParser()
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
return new Array<ValueScoreTuple>();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Checks if a given item exists within the KV stores Bloom Filter.
|
|
140
|
+
* @param {string} key The key for the Bloom Filter.
|
|
141
|
+
* @param {string} item The item to check for existence.
|
|
142
|
+
* @returns {boolean} True if the item exists, false otherwise.
|
|
143
|
+
*/
|
|
144
|
+
bfExists(key: string, item: string): boolean {
|
|
145
|
+
const keyBuffer = String.UTF8.encode(key);
|
|
146
|
+
const itemBuffer = String.UTF8.encode(item);
|
|
147
|
+
const returnHandlerRef = new Reference<u32>();
|
|
148
|
+
|
|
149
|
+
const status = imports.proxy_kv_store_bf_exists(
|
|
150
|
+
this.getHandle(),
|
|
151
|
+
changetype<usize>(keyBuffer),
|
|
152
|
+
keyBuffer.byteLength,
|
|
153
|
+
changetype<usize>(itemBuffer),
|
|
154
|
+
itemBuffer.byteLength,
|
|
155
|
+
returnHandlerRef.ptr() as u32
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
if (status == WasmResultValues.Ok) {
|
|
159
|
+
return returnHandlerRef.data != 0;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Gets the handle of this KV store instance
|
|
166
|
+
* @returns The handle
|
|
167
|
+
*/
|
|
168
|
+
getHandle(): u32 {
|
|
169
|
+
return this.handle;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export class ValueScoreTuple {
|
|
174
|
+
value: ArrayBuffer;
|
|
175
|
+
score: number;
|
|
176
|
+
|
|
177
|
+
constructor(value: ArrayBuffer, score: number) {
|
|
178
|
+
this.value = value;
|
|
179
|
+
this.score = score;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ValueScoreTuple parser implementation
|
|
184
|
+
class ValueScoreTupleParser extends ItemParser<ValueScoreTuple> {
|
|
185
|
+
parseItem(
|
|
186
|
+
buffer: ArrayBuffer,
|
|
187
|
+
dataIndex: u32,
|
|
188
|
+
itemSize: u32
|
|
189
|
+
): ValueScoreTuple | null {
|
|
190
|
+
// Each item contains value bytes + 8-byte f64 score
|
|
191
|
+
const scoreSize: u32 = 8; // f64 = 8 bytes
|
|
192
|
+
if (itemSize < scoreSize) {
|
|
193
|
+
// Invalid item, skip
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const valueSize = itemSize - scoreSize;
|
|
198
|
+
|
|
199
|
+
// Extract value data
|
|
200
|
+
const valueData = buffer.slice(
|
|
201
|
+
<i32>dataIndex,
|
|
202
|
+
<i32>(dataIndex + valueSize)
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Extract score data (last 8 bytes of the item)
|
|
206
|
+
const scoreData = buffer.slice(
|
|
207
|
+
<i32>(dataIndex + valueSize),
|
|
208
|
+
<i32>(dataIndex + itemSize)
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// Convert score bytes to f64 (little-endian)
|
|
212
|
+
const scoreBytes = new Uint8Array(scoreSize);
|
|
213
|
+
const sourceScoreBytes = Uint8Array.wrap(scoreData);
|
|
214
|
+
for (let j: u32 = 0; j < scoreSize; j++) {
|
|
215
|
+
scoreBytes[j] = sourceScoreBytes[j];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Convert little-endian bytes to f64
|
|
219
|
+
const scoreView = new DataView(scoreBytes.buffer);
|
|
220
|
+
const score = scoreView.getFloat64(0, true); // true = little-endian
|
|
221
|
+
|
|
222
|
+
return new ValueScoreTuple(valueData, score);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
createEmptyArray(): Array<ValueScoreTuple> {
|
|
226
|
+
return new Array<ValueScoreTuple>();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as imports from "../imports";
|
|
2
|
+
|
|
3
|
+
import { globalArrayBufferReference, WasmResultValues } from "../runtime";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Function to get the value for the provided secret variable name.
|
|
7
|
+
* @param {string} name - The name of the secret variable.
|
|
8
|
+
* @returns {string} The value of the secret variable.
|
|
9
|
+
*/
|
|
10
|
+
function getSecretVar(name: string): string {
|
|
11
|
+
const buffer = String.UTF8.encode(name);
|
|
12
|
+
const status = imports.proxy_get_secret(
|
|
13
|
+
changetype<usize>(buffer),
|
|
14
|
+
buffer.byteLength,
|
|
15
|
+
globalArrayBufferReference.bufferPtr(),
|
|
16
|
+
globalArrayBufferReference.sizePtr()
|
|
17
|
+
);
|
|
18
|
+
if (status == WasmResultValues.Ok) {
|
|
19
|
+
const arrBuff = globalArrayBufferReference.toArrayBuffer();
|
|
20
|
+
if (arrBuff.byteLength > 0) {
|
|
21
|
+
return String.UTF8.decode(arrBuff);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Function to get the value for the provided secret variable name from a specific slot.
|
|
29
|
+
* @param {string} name - The name of the secret variable.
|
|
30
|
+
* @param {u32} effectiveAt - The slot index of the secret. (effectiveAt >= secret_slots.slot)
|
|
31
|
+
* @returns {string} The value of the secret variable.
|
|
32
|
+
*/
|
|
33
|
+
function getSecretVarEffectiveAt(name: string, effectiveAt: u32): string {
|
|
34
|
+
const buffer = String.UTF8.encode(name);
|
|
35
|
+
const status = imports.proxy_get_effective_at_secret(
|
|
36
|
+
changetype<usize>(buffer),
|
|
37
|
+
buffer.byteLength,
|
|
38
|
+
effectiveAt,
|
|
39
|
+
globalArrayBufferReference.bufferPtr(),
|
|
40
|
+
globalArrayBufferReference.sizePtr()
|
|
41
|
+
);
|
|
42
|
+
if (status == WasmResultValues.Ok) {
|
|
43
|
+
const arrBuff = globalArrayBufferReference.toArrayBuffer();
|
|
44
|
+
if (arrBuff.byteLength > 0) {
|
|
45
|
+
return String.UTF8.decode(arrBuff);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { getSecretVar, getSecretVarEffectiveAt };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Abstract base class for item parsers
|
|
2
|
+
abstract class ItemParser<T> {
|
|
3
|
+
abstract parseItem(
|
|
4
|
+
buffer: ArrayBuffer,
|
|
5
|
+
dataIndex: u32,
|
|
6
|
+
itemSize: u32
|
|
7
|
+
): T | null;
|
|
8
|
+
abstract createEmptyArray(): Array<T>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// String parser implementation
|
|
12
|
+
class StringParser extends ItemParser<string> {
|
|
13
|
+
parseItem(buffer: ArrayBuffer, dataIndex: u32, itemSize: u32): string | null {
|
|
14
|
+
// Extract string data
|
|
15
|
+
const stringData = buffer.slice(
|
|
16
|
+
<i32>dataIndex,
|
|
17
|
+
<i32>(dataIndex + itemSize)
|
|
18
|
+
);
|
|
19
|
+
return String.UTF8.decode(stringData);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
createEmptyArray(): Array<string> {
|
|
23
|
+
return new Array<string>();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Generic deserialization function
|
|
28
|
+
function parseBufferToList<T>(
|
|
29
|
+
buffer: ArrayBuffer,
|
|
30
|
+
parser: ItemParser<T>
|
|
31
|
+
): Array<T> {
|
|
32
|
+
// Check if buffer is valid
|
|
33
|
+
if (!buffer || buffer.byteLength === 0) {
|
|
34
|
+
return parser.createEmptyArray();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Read number of items
|
|
38
|
+
const numItems = Uint32Array.wrap(buffer, 0, 1)[0];
|
|
39
|
+
|
|
40
|
+
if (numItems === 0) {
|
|
41
|
+
return parser.createEmptyArray();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Read sizes array
|
|
45
|
+
const sizes = Uint32Array.wrap(buffer, sizeof<u32>(), numItems);
|
|
46
|
+
|
|
47
|
+
// Start of actual data
|
|
48
|
+
let dataIndex: u32 = sizeof<u32>() * (1 + numItems);
|
|
49
|
+
const result = parser.createEmptyArray();
|
|
50
|
+
|
|
51
|
+
for (let i: u32 = 0; i < numItems; i++) {
|
|
52
|
+
const itemSize = sizes[i];
|
|
53
|
+
|
|
54
|
+
if (dataIndex + itemSize > <u32>buffer.byteLength) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const item = parser.parseItem(buffer, dataIndex, itemSize);
|
|
59
|
+
if (item !== null) {
|
|
60
|
+
result.push(item);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Move to next item (including null terminator if present)
|
|
64
|
+
dataIndex += itemSize + 1; // +1 for null terminator
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { ItemParser, StringParser, parseBufferToList };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { get_current_time_nanoseconds, LogLevelValues } from "../../runtime";
|
|
2
|
+
|
|
3
|
+
let logLevel: LogLevelValues = LogLevelValues.info;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sets the logging level, proxy_get_log_level is not yet implemented in FastEdge.
|
|
7
|
+
* @param {LogLevelValues} level The logging level to set.
|
|
8
|
+
* @returns {void}
|
|
9
|
+
*/
|
|
10
|
+
function setLogLevel(level: LogLevelValues): void {
|
|
11
|
+
logLevel = level;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Temporary fix for proxy_log not being implemented in FastEdge.
|
|
16
|
+
* The function relies on @assemblyscript/wasi-shim to print to standard output.
|
|
17
|
+
* @param {LogLevelValues} level The logging level to use.
|
|
18
|
+
* @param {string} logMessage The logging message to log.
|
|
19
|
+
* @returns {void}
|
|
20
|
+
*/
|
|
21
|
+
function log(level: LogLevelValues, logMessage: string): void {
|
|
22
|
+
if (level >= logLevel) {
|
|
23
|
+
process.stdout.write(logMessage + "\n");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getCurrentTime(): u64 {
|
|
28
|
+
return get_current_time_nanoseconds() / 1_000_000; // Convert nanoseconds to milliseconds
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { getCurrentTime, log, LogLevelValues, setLogLevel };
|
package/assembly/imports.ts
CHANGED
|
@@ -201,3 +201,68 @@ export declare function proxy_get_effective_at_secret(
|
|
|
201
201
|
return_value_size: usize
|
|
202
202
|
): u32;
|
|
203
203
|
|
|
204
|
+
|
|
205
|
+
// KV Store
|
|
206
|
+
// @ts-ignore: decorator
|
|
207
|
+
@external("env", "proxy_kv_store_open")
|
|
208
|
+
export declare function proxy_kv_store_open(
|
|
209
|
+
key_data: usize,
|
|
210
|
+
key_size: usize,
|
|
211
|
+
return_handle: u32
|
|
212
|
+
): u32;
|
|
213
|
+
|
|
214
|
+
// @ts-ignore: decorator
|
|
215
|
+
@external("env", "proxy_kv_store_get")
|
|
216
|
+
export declare function proxy_kv_store_get(
|
|
217
|
+
handle: u32,
|
|
218
|
+
key_data: usize,
|
|
219
|
+
key_size: usize,
|
|
220
|
+
return_value_data: usize,
|
|
221
|
+
return_value_size: usize,
|
|
222
|
+
): u32;
|
|
223
|
+
|
|
224
|
+
// @ts-ignore: decorator
|
|
225
|
+
@external("env", "proxy_kv_store_scan")
|
|
226
|
+
export declare function proxy_kv_store_scan(
|
|
227
|
+
handle: u32,
|
|
228
|
+
pattern_data: usize,
|
|
229
|
+
pattern_size: usize,
|
|
230
|
+
return_value_data: usize,
|
|
231
|
+
return_value_size: usize,
|
|
232
|
+
): u32;
|
|
233
|
+
|
|
234
|
+
// @ts-ignore: decorator
|
|
235
|
+
@external("env", "proxy_kv_store_zrange_by_score")
|
|
236
|
+
export declare function proxy_kv_store_zrange_by_score(
|
|
237
|
+
handle: u32,
|
|
238
|
+
key_data: usize,
|
|
239
|
+
key_size: usize,
|
|
240
|
+
min: f64,
|
|
241
|
+
max: f64,
|
|
242
|
+
return_value_data: usize,
|
|
243
|
+
return_value_size: usize,
|
|
244
|
+
): u32;
|
|
245
|
+
|
|
246
|
+
// @ts-ignore: decorator
|
|
247
|
+
@external("env", "proxy_kv_store_zscan")
|
|
248
|
+
export declare function proxy_kv_store_zscan(
|
|
249
|
+
handle: u32,
|
|
250
|
+
key_data: usize,
|
|
251
|
+
key_size: usize,
|
|
252
|
+
pattern_data: usize,
|
|
253
|
+
pattern_size: usize,
|
|
254
|
+
return_value_data: usize,
|
|
255
|
+
return_value_size: usize,
|
|
256
|
+
): u32;
|
|
257
|
+
|
|
258
|
+
// @ts-ignore: decorator
|
|
259
|
+
@external("env", "proxy_kv_store_bf_exists")
|
|
260
|
+
export declare function proxy_kv_store_bf_exists(
|
|
261
|
+
handle: u32,
|
|
262
|
+
key_data: usize,
|
|
263
|
+
key_size: usize,
|
|
264
|
+
item_data: usize,
|
|
265
|
+
item_size: usize,
|
|
266
|
+
return_handle: u32,
|
|
267
|
+
): u32;
|
|
268
|
+
|
package/assembly/index.ts
CHANGED
package/assembly/runtime.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { free } from "./malloc";
|
|
|
3
3
|
|
|
4
4
|
import { log as wasiLog } from "./fastedge";
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
// abort function.
|
|
7
8
|
// use with:
|
|
8
9
|
// --use abort=index/abort_proc_exit
|
|
@@ -32,7 +33,6 @@ function CHECK_RESULT(c: imports.WasmResult): void {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/////////////// Access helpers
|
|
35
|
-
|
|
36
36
|
export class Reference<T> {
|
|
37
37
|
data: T;
|
|
38
38
|
|
|
@@ -55,8 +55,12 @@ class ArrayBufferReference {
|
|
|
55
55
|
return changetype<usize>(this) + offsetof<ArrayBufferReference>("buffer");
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Before calling toArrayBuffer below, you must call out to the host to fill in the values.
|
|
60
|
+
* toArrayBuffer below **must** be called once and only once.
|
|
61
|
+
* Host code used malloc to allocate this buffer.
|
|
62
|
+
* This method consumes the buffer and handles memory cleanup automatically.
|
|
63
|
+
*/
|
|
60
64
|
toArrayBuffer(): ArrayBuffer {
|
|
61
65
|
if (this.size == 0) {
|
|
62
66
|
return new ArrayBuffer(0);
|
|
@@ -71,6 +75,8 @@ class ArrayBufferReference {
|
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
|
|
79
|
+
|
|
74
80
|
export const globalArrayBufferReference = new ArrayBufferReference();
|
|
75
81
|
let globalU32Ref = new Reference<u32>();
|
|
76
82
|
let globalLogLevelRef = new Reference<imports.LogLevel>();
|
|
@@ -633,7 +639,6 @@ export function get_buffer_bytes(typ: BufferTypeValues, start: u32, length: u32)
|
|
|
633
639
|
|
|
634
640
|
export function set_buffer_bytes(typ: BufferTypeValues, start: u32, length: u32, value: ArrayBuffer): WasmResultValues {
|
|
635
641
|
const result = imports.proxy_set_buffer_bytes(typ, start, length, changetype<usize>(value), value.byteLength);
|
|
636
|
-
wasiLog(LogLevelValues.info, 'Farq: setBuffer result: ' + result.toString());
|
|
637
642
|
return result
|
|
638
643
|
}
|
|
639
644
|
|
package/package.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "@gcoredev/proxy-wasm-sdk-as",
|
|
3
|
+
"description": "Use this SDK to write extensions for the proxy WASM ABI",
|
|
4
|
+
"version": "1.2.1-alpha.1",
|
|
5
|
+
"main": "assembly/index.ts",
|
|
2
6
|
"scripts": {
|
|
3
7
|
"asbuild:debug": "asc assembly/index.ts --target debug",
|
|
4
8
|
"asbuild:release": "asc assembly/index.ts --target release",
|
|
@@ -15,10 +19,6 @@
|
|
|
15
19
|
"minimist": ">=1.2.2",
|
|
16
20
|
"typedoc": "^0.27.7"
|
|
17
21
|
},
|
|
18
|
-
"name": "@gcoredev/proxy-wasm-sdk-as",
|
|
19
|
-
"description": "Use this SDK to write extensions for the proxy WASM ABI",
|
|
20
|
-
"version": "1.1.0",
|
|
21
|
-
"main": "assembly/index.ts",
|
|
22
22
|
"directories": {
|
|
23
23
|
"doc": "docs"
|
|
24
24
|
},
|
package/assembly/fastedge.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import * as imports from "./imports";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
get_current_time_nanoseconds,
|
|
5
|
-
globalArrayBufferReference,
|
|
6
|
-
LogLevelValues,
|
|
7
|
-
} from "./runtime";
|
|
8
|
-
|
|
9
|
-
let logLevel: LogLevelValues = LogLevelValues.info;
|
|
10
|
-
|
|
11
|
-
function setLogLevel(level: LogLevelValues): void {
|
|
12
|
-
logLevel = level;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function log(level: LogLevelValues, logMessage: string): void {
|
|
16
|
-
// Temporary fix for proxy_log not being implemented in fastedge:
|
|
17
|
-
// relies on @assemblyscript/wasi-shim to print to standard output
|
|
18
|
-
if (level >= logLevel) {
|
|
19
|
-
process.stdout.write(logMessage + "\n");
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getCurrentTime(): u64 {
|
|
24
|
-
return get_current_time_nanoseconds() / 1_000_000; // Convert nanoseconds to milliseconds
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function getEnvVar(key: string): string {
|
|
28
|
-
const hasKey = process.env.has(key);
|
|
29
|
-
if (hasKey) {
|
|
30
|
-
return process.env.get(key);
|
|
31
|
-
}
|
|
32
|
-
return "";
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function getSecretVar(key: string): string {
|
|
36
|
-
const buffer = String.UTF8.encode(key);
|
|
37
|
-
const status = imports.proxy_get_secret(
|
|
38
|
-
changetype<usize>(buffer),
|
|
39
|
-
buffer.byteLength,
|
|
40
|
-
globalArrayBufferReference.bufferPtr(),
|
|
41
|
-
globalArrayBufferReference.sizePtr()
|
|
42
|
-
);
|
|
43
|
-
if (status != 0) {
|
|
44
|
-
// Something went wrong - returns 0 with an empty ArrayBuffer if not found
|
|
45
|
-
return "";
|
|
46
|
-
}
|
|
47
|
-
const arrBuff = globalArrayBufferReference.toArrayBuffer();
|
|
48
|
-
if (arrBuff.byteLength == 0) {
|
|
49
|
-
return ""; // Not found
|
|
50
|
-
}
|
|
51
|
-
return String.UTF8.decode(arrBuff);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function getSecretVarEffectiveAt(key: string, at: u32): string {
|
|
55
|
-
const buffer = String.UTF8.encode(key);
|
|
56
|
-
const status = imports.proxy_get_effective_at_secret(
|
|
57
|
-
changetype<usize>(buffer),
|
|
58
|
-
buffer.byteLength,
|
|
59
|
-
at,
|
|
60
|
-
globalArrayBufferReference.bufferPtr(),
|
|
61
|
-
globalArrayBufferReference.sizePtr()
|
|
62
|
-
);
|
|
63
|
-
if (status != 0) {
|
|
64
|
-
// Something went wrong - returns 0 with an empty ArrayBuffer if not found
|
|
65
|
-
return "";
|
|
66
|
-
}
|
|
67
|
-
const arrBuff = globalArrayBufferReference.toArrayBuffer();
|
|
68
|
-
if (arrBuff.byteLength == 0) {
|
|
69
|
-
return ""; // Not found
|
|
70
|
-
}
|
|
71
|
-
return String.UTF8.decode(arrBuff);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export {
|
|
75
|
-
getCurrentTime,
|
|
76
|
-
getEnvVar,
|
|
77
|
-
getSecretVar,
|
|
78
|
-
getSecretVarEffectiveAt,
|
|
79
|
-
log,
|
|
80
|
-
LogLevelValues,
|
|
81
|
-
setLogLevel,
|
|
82
|
-
};
|