gpt-tokenizer 1.0.2 → 1.0.4

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.
Files changed (59) hide show
  1. package/cjs/data/bpeRanks.d.ts +50003 -0
  2. package/cjs/data/bpeRanks.js +7 -0
  3. package/cjs/data/bpeRanks.js.map +1 -0
  4. package/cjs/data/encoder.d.ts +50260 -0
  5. package/cjs/data/encoder.js +7 -0
  6. package/cjs/data/encoder.js.map +1 -0
  7. package/cjs/{getBpe.js → getData.js} +6 -2
  8. package/cjs/getData.js.map +1 -0
  9. package/cjs/main.d.ts +28 -1
  10. package/cjs/main.js +208 -14
  11. package/cjs/main.js.map +1 -1
  12. package/cjs/main.test.js +86 -0
  13. package/cjs/main.test.js.map +1 -0
  14. package/cjs/utils.d.ts +22 -6
  15. package/cjs/utils.js +29 -1
  16. package/cjs/utils.js.map +1 -1
  17. package/esm/data/bpeRanks.d.ts +50003 -0
  18. package/esm/data/bpeRanks.js +5 -0
  19. package/esm/data/bpeRanks.js.map +1 -0
  20. package/esm/data/encoder.d.ts +50260 -0
  21. package/esm/data/encoder.js +5 -0
  22. package/esm/data/encoder.js.map +1 -0
  23. package/esm/getData.js +16 -0
  24. package/esm/getData.js.map +1 -0
  25. package/esm/main.d.ts +28 -1
  26. package/esm/main.js +196 -1
  27. package/esm/main.js.map +1 -1
  28. package/esm/{encoder.test.js → main.test.js} +2 -2
  29. package/esm/main.test.js.map +1 -0
  30. package/esm/package.json +1 -0
  31. package/esm/utils.d.ts +22 -6
  32. package/esm/utils.js +29 -1
  33. package/esm/utils.js.map +1 -1
  34. package/package.json +8 -4
  35. package/src/data/bpeRanks.js +4 -0
  36. package/src/data/encoder.js +4 -0
  37. package/src/getData.ts +34 -0
  38. package/src/{encoder.test.ts → main.test.ts} +1 -1
  39. package/src/main.ts +266 -1
  40. package/src/utils.js +61 -0
  41. package/cjs/encoder.d.ts +0 -16
  42. package/cjs/encoder.js +0 -201
  43. package/cjs/encoder.js.map +0 -1
  44. package/cjs/encoder.test.js +0 -86
  45. package/cjs/encoder.test.js.map +0 -1
  46. package/cjs/getBpe.js.map +0 -1
  47. package/esm/encoder.d.ts +0 -16
  48. package/esm/encoder.js +0 -188
  49. package/esm/encoder.js.map +0 -1
  50. package/esm/encoder.test.js.map +0 -1
  51. package/esm/getBpe.js +0 -12
  52. package/esm/getBpe.js.map +0 -1
  53. package/src/encoder.ts +0 -252
  54. package/src/getBpe.ts +0 -23
  55. package/src/utils.ts +0 -36
  56. /package/cjs/{encoder.test.d.ts → getData.d.ts} +0 -0
  57. /package/cjs/{getBpe.d.ts → main.test.d.ts} +0 -0
  58. /package/esm/{encoder.test.d.ts → getData.d.ts} +0 -0
  59. /package/esm/{getBpe.d.ts → main.test.d.ts} +0 -0
package/src/getData.ts ADDED
@@ -0,0 +1,34 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { dictZip, range } from './utils'
4
+
5
+ const bpeFile = fs.readFileSync(
6
+ path.join(__dirname, '../data/vocab.bpe'),
7
+ 'utf8',
8
+ )
9
+ const lines = bpeFile.split('\n')
10
+
11
+ const bpeMerges = lines.slice(1, -1).map((x) =>
12
+ x
13
+ .split(/(\s+)/)
14
+ .filter((e) => e.trim().length > 0)
15
+ .join(','),
16
+ )
17
+
18
+ const bpeRanks = dictZip(bpeMerges, range(0, bpeMerges.length))
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
20
+ const encoder: object = require('../data/encoder.json')
21
+
22
+ fs.mkdirSync(path.join(__dirname, 'data'), { recursive: true })
23
+ fs.writeFileSync(
24
+ path.join(__dirname, 'data/bpeRanks.js'),
25
+ `/* eslint-disable */\n// @ts-nocheck\n// prettier-ignore\nexport default ${JSON.stringify(
26
+ bpeRanks,
27
+ )}`,
28
+ )
29
+ fs.writeFileSync(
30
+ path.join(__dirname, 'data/encoder.js'),
31
+ `/* eslint-disable */\n// @ts-nocheck\n// prettier-ignore\nexport default ${JSON.stringify(
32
+ encoder,
33
+ )}`,
34
+ )
@@ -5,7 +5,7 @@ import {
5
5
  decodeGenerator,
6
6
  encode,
7
7
  isWithinTokenLimit,
8
- } from './encoder'
8
+ } from './main'
9
9
 
10
10
  describe('basic functionality', () => {
11
11
  it('empty string', () => {
package/src/main.ts CHANGED
@@ -1 +1,266 @@
1
- export * from './encoder'
1
+ /* eslint-disable import/extensions */
2
+ /* eslint-disable unicorn/prefer-spread */
3
+ /* eslint-disable unicorn/prefer-code-point */
4
+
5
+ import bpeRanksData from './data/bpeRanks.js'
6
+ import encoderData from './data/encoder.js'
7
+ import {
8
+ dictZip,
9
+ getCharCode,
10
+ getCharFromCode,
11
+ getPairs,
12
+ range,
13
+ splitToken,
14
+ } from './utils.js'
15
+
16
+ const encoder: Record<string, number> = encoderData
17
+ const bpeRanks: Record<string, number> = bpeRanksData
18
+
19
+ const decoder: Record<number, string> = dictZip(
20
+ Object.values(encoder),
21
+ Object.keys(encoder),
22
+ )
23
+
24
+ const textEncoder = new TextEncoder()
25
+ const textDecoder = new TextDecoder()
26
+
27
+ // eslint-disable-next-line no-magic-numbers
28
+ const UPPER_BYTE_VALUE = 2 ** 8
29
+
30
+ function createByteToUnicodeMap(): Map<number, string> {
31
+ const asciiRange = range(getCharCode('!'), getCharCode('~') + 1)
32
+ const latin1Range1 = range(getCharCode('¡'), getCharCode('¬') + 1)
33
+ const latin1Range2 = range(getCharCode('®'), getCharCode('ÿ') + 1)
34
+
35
+ const initialCodePoints = [...asciiRange, ...latin1Range1, ...latin1Range2]
36
+ const mappedCodePoints = [...initialCodePoints]
37
+
38
+ let newCodePointOffset = 0
39
+ for (let byteValue = 0; byteValue < UPPER_BYTE_VALUE; byteValue++) {
40
+ if (!initialCodePoints.includes(byteValue)) {
41
+ initialCodePoints.push(byteValue)
42
+ mappedCodePoints.push(UPPER_BYTE_VALUE + newCodePointOffset)
43
+ newCodePointOffset += 1
44
+ }
45
+ }
46
+
47
+ const unicodeChars = mappedCodePoints.map(getCharFromCode)
48
+ return new Map(initialCodePoints.map((x, i) => [x, unicodeChars[i]!]))
49
+ }
50
+
51
+ const pat =
52
+ /'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu
53
+
54
+ const byteEncoder = createByteToUnicodeMap()
55
+ const byteDecoder: Map<string, number> = new Map(
56
+ [...byteEncoder].map(([k, v]) => [v, k]),
57
+ )
58
+
59
+ export function bpe(
60
+ token: string,
61
+ cache: Map<string, string> = new Map(),
62
+ ): string {
63
+ if (cache.has(token)) {
64
+ return cache.get(token)!
65
+ }
66
+
67
+ let word = splitToken(token)
68
+ let pairs = getPairs(word)
69
+
70
+ if (pairs.length === 0) {
71
+ return token
72
+ }
73
+
74
+ // eslint-disable-next-line no-constant-condition
75
+ while (true) {
76
+ const minPairs: Map<number, [string, string]> = new Map()
77
+ pairs.forEach((pair) => {
78
+ const rank = bpeRanks[pair.join(',')]
79
+ minPairs.set(
80
+ // eslint-disable-next-line no-magic-numbers
81
+ typeof rank === 'undefined' || Number.isNaN(rank) ? 10e10 : rank,
82
+ pair,
83
+ )
84
+ })
85
+ const keys = [...minPairs.keys()]
86
+
87
+ const bigram = minPairs.get(Math.min(...keys))
88
+
89
+ if (!bigram || !(bigram.join(',') in bpeRanks)) {
90
+ break
91
+ }
92
+
93
+ const [first, second] = bigram
94
+ let newWord: string[] = []
95
+ let i = 0
96
+
97
+ while (i < word.length) {
98
+ const j = word.indexOf(first, i)
99
+ if (j === -1) {
100
+ newWord = newWord.concat(word.slice(i))
101
+ break
102
+ }
103
+ newWord = newWord.concat(word.slice(i, j))
104
+ i = j
105
+
106
+ if (word[i] === first && i < word.length - 1 && word[i + 1] === second) {
107
+ newWord.push(first + second)
108
+ i += 2
109
+ } else {
110
+ newWord.push(word[i]!)
111
+ i += 1
112
+ }
113
+ }
114
+
115
+ word = newWord
116
+ if (word.length === 1) {
117
+ break
118
+ } else {
119
+ pairs = getPairs(word)
120
+ }
121
+ }
122
+
123
+ const result = word.join(' ')
124
+ cache.set(token, result)
125
+
126
+ return result
127
+ }
128
+
129
+ export function* encodeGenerator(
130
+ text: string,
131
+ cache: Map<string, string> = new Map(),
132
+ ): Generator<number[], void, undefined> {
133
+ for (let [token] of text.matchAll(pat)) {
134
+ token = [...textEncoder.encode(token)]
135
+ .map((x) => byteEncoder.get(x) ?? '')
136
+ .join('')
137
+
138
+ const newTokens = bpe(token, cache)
139
+ .split(' ')
140
+ .map((x) => encoder[x]!)
141
+
142
+ yield newTokens
143
+ }
144
+ }
145
+
146
+ /**
147
+ * @returns {false | number} false if token limit is exceeded, otherwise the number of tokens
148
+ */
149
+ export function isWithinTokenLimit(
150
+ text: string,
151
+ tokenLimit: number,
152
+ cache: Map<string, string> = new Map(),
153
+ ): false | number {
154
+ const tokenGenerator = encodeGenerator(text, cache)
155
+ let count = 0
156
+ for (const tokens of tokenGenerator) {
157
+ count += tokens.length
158
+ if (count > tokenLimit) {
159
+ return false
160
+ }
161
+ }
162
+ return count
163
+ }
164
+
165
+ export function encode(
166
+ text: string,
167
+ cache: Map<string, string> = new Map(),
168
+ ): number[] {
169
+ return [...encodeGenerator(text, cache)].flat(1)
170
+ }
171
+
172
+ export function decodeToken(token: number): string {
173
+ const decodedToken = decoder[token]
174
+ if (typeof decodedToken === 'undefined') {
175
+ return ''
176
+ }
177
+ const decodedBytes = splitToken(decodedToken).map((x) => byteDecoder.get(x)!)
178
+ return textDecoder.decode(new Uint8Array(decodedBytes), {
179
+ stream: true,
180
+ })
181
+ }
182
+
183
+ const HIGH_SURROGATE_START = 55_296
184
+ const HIGH_SURROGATE_END = 56_319
185
+ export function endsWithIncompleteUtfPairSurrogate(string: string): boolean {
186
+ if (string.length === 0) return false
187
+ // Check if the last character is a high surrogate
188
+ const lastCharCode = string.charCodeAt(string.length - 1)
189
+ return (
190
+ lastCharCode >= HIGH_SURROGATE_START && lastCharCode <= HIGH_SURROGATE_END
191
+ )
192
+ }
193
+
194
+ export function* decodeGenerator(
195
+ tokens: Iterable<number>,
196
+ ): Generator<string, void, undefined> {
197
+ let buffer = ''
198
+
199
+ for (const token of tokens) {
200
+ buffer += decodeToken(token)
201
+
202
+ if (buffer.length === 0 || endsWithIncompleteUtfPairSurrogate(buffer)) {
203
+ // Keep the high surrogate in the buffer and continue with the next token
204
+ // eslint-disable-next-line no-continue
205
+ continue
206
+ } else {
207
+ yield buffer
208
+ // reset buffer
209
+ buffer = ''
210
+ }
211
+ }
212
+
213
+ // Yield any remaining characters in the buffer
214
+ if (buffer.length > 0) {
215
+ yield buffer
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Decode tokens asynchronously and yield the decoded strings, one by one.
221
+ * Will not yield for tokens that include a high surrogate, but wait for the next token.
222
+ * @param {AsyncIterable<number>} tokens
223
+ * @returns {AsyncGenerator<string, void, undefined>}
224
+ */
225
+ export async function* decodeAsyncGenerator(
226
+ tokens: AsyncIterable<number>,
227
+ ): AsyncGenerator<string, void, undefined> {
228
+ let buffer = ''
229
+
230
+ for await (const token of tokens) {
231
+ buffer += decodeToken(token)
232
+
233
+ if (buffer.length === 0 || endsWithIncompleteUtfPairSurrogate(buffer)) {
234
+ // Keep the high surrogate in the buffer and continue with the next token
235
+ // eslint-disable-next-line no-continue
236
+ continue
237
+ } else {
238
+ yield buffer
239
+ // reset buffer
240
+ buffer = ''
241
+ }
242
+ }
243
+
244
+ // Yield any remaining characters in the buffer
245
+ if (buffer.length > 0) {
246
+ yield buffer
247
+ }
248
+ }
249
+
250
+ export function decode(tokens: number[]): string {
251
+ return [...decodeGenerator(tokens)].join('')
252
+ }
253
+
254
+ const gptEncoder = {
255
+ encode,
256
+ decode,
257
+ encodeGenerator,
258
+ decodeGenerator,
259
+ decodeAsyncGenerator,
260
+ isWithinTokenLimit,
261
+ bpe,
262
+ }
263
+
264
+ // used by the UMD export
265
+ // eslint-disable-next-line import/no-default-export
266
+ export default gptEncoder
package/src/utils.js ADDED
@@ -0,0 +1,61 @@
1
+ /* eslint-disable unicorn/prefer-spread */
2
+ /* eslint-disable unicorn/prefer-code-point */
3
+
4
+ /**
5
+ * @template T
6
+ * @template U
7
+ * @param {T[]} x
8
+ * @param {U[]} y
9
+ * @returns {Record<T, U>}
10
+ */
11
+ export function dictZip(x, y) {
12
+ /** @type {Record<T, U>} */
13
+ const result = {}
14
+ x.forEach((k, i) => {
15
+ result[k] = y[i]
16
+ })
17
+ return result
18
+ }
19
+
20
+ /**
21
+ * @param {number} x
22
+ * @param {number} y
23
+ * @returns {number[]}
24
+ */
25
+ export function range(x, y) {
26
+ return Array.from({ length: y - x }, (_, i) => x + i)
27
+ }
28
+
29
+ /**
30
+ * @param {string} x
31
+ * @returns {number}
32
+ */
33
+ export const getCharCode = (x) => x.charCodeAt(0)
34
+
35
+ /**
36
+ * @param {number} x
37
+ * @returns {string}
38
+ */
39
+ export const getCharFromCode = (x) => String.fromCharCode(x)
40
+
41
+ /**
42
+ * @param {string[]} word
43
+ * @returns {[string, string][]}
44
+ */
45
+ export function getPairs(word) {
46
+ /** @type {[string, string][]} */
47
+ const pairs = []
48
+ let prevChar = word[0]
49
+ for (let i = 1; i < word.length; i++) {
50
+ const char = word[i]
51
+ pairs.push([prevChar, char])
52
+ prevChar = char
53
+ }
54
+ return pairs
55
+ }
56
+
57
+ /**
58
+ * @param {string} token
59
+ * @returns {string[]}
60
+ */
61
+ export const splitToken = (token) => token.split('')
package/cjs/encoder.d.ts DELETED
@@ -1,16 +0,0 @@
1
- /**
2
- * @returns {false | number} false if token limit is exceeded, otherwise the number of tokens
3
- */
4
- export declare function isWithinTokenLimit(text: string, tokenLimit: number, cache?: Map<string, string>): false | number;
5
- export declare function encode(text: string, cache?: Map<string, string>): number[];
6
- export declare function decodeToken(token: number): string;
7
- export declare function endsWithIncompleteUtfPairSurrogate(string: string): boolean;
8
- export declare function decodeGenerator(tokens: Iterable<number>): Generator<string, void, undefined>;
9
- /**
10
- * Decode tokens asynchronously and yield the decoded strings, one by one.
11
- * Will not yield for tokens that include a high surrogate, but wait for the next token.
12
- * @param {AsyncIterable<number>} tokens
13
- * @returns {AsyncGenerator<string, void, undefined>}
14
- */
15
- export declare function decodeAsyncGenerator(tokens: AsyncIterable<number>): AsyncGenerator<string, void, undefined>;
16
- export declare function decode(tokens: number[]): string;
package/cjs/encoder.js DELETED
@@ -1,201 +0,0 @@
1
- "use strict";
2
- /* eslint-disable unicorn/prefer-spread */
3
- /* eslint-disable unicorn/prefer-code-point */
4
- var __importDefault = (this && this.__importDefault) || function (mod) {
5
- return (mod && mod.__esModule) ? mod : { "default": mod };
6
- };
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.decode = exports.decodeAsyncGenerator = exports.decodeGenerator = exports.endsWithIncompleteUtfPairSurrogate = exports.decodeToken = exports.encode = exports.isWithinTokenLimit = void 0;
9
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
10
- // @ts-ignore
11
- const bpeRanks_json_1 = __importDefault(require("../data/bpeRanks.json"));
12
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
13
- // @ts-ignore
14
- const encoder_json_1 = __importDefault(require("../data/encoder.json"));
15
- const utils_1 = require("./utils");
16
- const encoder = encoder_json_1.default;
17
- const bpeRanks = bpeRanks_json_1.default;
18
- const decoder = (0, utils_1.dictZip)(Object.values(encoder), Object.keys(encoder));
19
- const textEncoder = new TextEncoder();
20
- const textDecoder = new TextDecoder();
21
- // eslint-disable-next-line no-magic-numbers
22
- const UPPER_BYTE_VALUE = 2 ** 8;
23
- function createByteToUnicodeMap() {
24
- const asciiRange = (0, utils_1.range)((0, utils_1.getCharCode)('!'), (0, utils_1.getCharCode)('~') + 1);
25
- const latin1Range1 = (0, utils_1.range)((0, utils_1.getCharCode)('¡'), (0, utils_1.getCharCode)('¬') + 1);
26
- const latin1Range2 = (0, utils_1.range)((0, utils_1.getCharCode)('®'), (0, utils_1.getCharCode)('ÿ') + 1);
27
- const initialCodePoints = [...asciiRange, ...latin1Range1, ...latin1Range2];
28
- const mappedCodePoints = [...initialCodePoints];
29
- let newCodePointOffset = 0;
30
- for (let byteValue = 0; byteValue < UPPER_BYTE_VALUE; byteValue++) {
31
- if (!initialCodePoints.includes(byteValue)) {
32
- initialCodePoints.push(byteValue);
33
- mappedCodePoints.push(UPPER_BYTE_VALUE + newCodePointOffset);
34
- newCodePointOffset += 1;
35
- }
36
- }
37
- const unicodeChars = mappedCodePoints.map(utils_1.getCharFromCode);
38
- return new Map(initialCodePoints.map((x, i) => [x, unicodeChars[i]]));
39
- }
40
- const pat = /'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu;
41
- const byteEncoder = createByteToUnicodeMap();
42
- const byteDecoder = new Map([...byteEncoder].map(([k, v]) => [v, k]));
43
- function bpe(token, cache = new Map()) {
44
- if (cache.has(token)) {
45
- return cache.get(token);
46
- }
47
- let word = (0, utils_1.splitToken)(token);
48
- let pairs = (0, utils_1.getPairs)(word);
49
- if (pairs.length === 0) {
50
- return token;
51
- }
52
- // eslint-disable-next-line no-constant-condition
53
- while (true) {
54
- const minPairs = new Map();
55
- pairs.forEach((pair) => {
56
- const rank = bpeRanks[pair.join(',')];
57
- minPairs.set(
58
- // eslint-disable-next-line no-magic-numbers
59
- typeof rank === 'undefined' || Number.isNaN(rank) ? 10e10 : rank, pair);
60
- });
61
- const keys = [...minPairs.keys()];
62
- const bigram = minPairs.get(Math.min(...keys));
63
- if (!bigram || !(bigram.join(',') in bpeRanks)) {
64
- break;
65
- }
66
- const [first, second] = bigram;
67
- let newWord = [];
68
- let i = 0;
69
- while (i < word.length) {
70
- const j = word.indexOf(first, i);
71
- if (j === -1) {
72
- newWord = newWord.concat(word.slice(i));
73
- break;
74
- }
75
- newWord = newWord.concat(word.slice(i, j));
76
- i = j;
77
- if (word[i] === first && i < word.length - 1 && word[i + 1] === second) {
78
- newWord.push(first + second);
79
- i += 2;
80
- }
81
- else {
82
- newWord.push(word[i]);
83
- i += 1;
84
- }
85
- }
86
- word = newWord;
87
- if (word.length === 1) {
88
- break;
89
- }
90
- else {
91
- pairs = (0, utils_1.getPairs)(word);
92
- }
93
- }
94
- const result = word.join(' ');
95
- cache.set(token, result);
96
- return result;
97
- }
98
- function* encodeGenerator(text, cache = new Map()) {
99
- for (let [token] of text.matchAll(pat)) {
100
- token = [...textEncoder.encode(token)]
101
- .map((x) => byteEncoder.get(x) ?? '')
102
- .join('');
103
- const newTokens = bpe(token, cache)
104
- .split(' ')
105
- .map((x) => encoder[x]);
106
- yield newTokens;
107
- }
108
- }
109
- /**
110
- * @returns {false | number} false if token limit is exceeded, otherwise the number of tokens
111
- */
112
- function isWithinTokenLimit(text, tokenLimit, cache = new Map()) {
113
- const tokenGenerator = encodeGenerator(text, cache);
114
- let count = 0;
115
- for (const tokens of tokenGenerator) {
116
- count += tokens.length;
117
- if (count > tokenLimit) {
118
- return false;
119
- }
120
- }
121
- return count;
122
- }
123
- exports.isWithinTokenLimit = isWithinTokenLimit;
124
- function encode(text, cache = new Map()) {
125
- return [...encodeGenerator(text, cache)].flat(1);
126
- }
127
- exports.encode = encode;
128
- function decodeToken(token) {
129
- const decodedToken = decoder[token];
130
- if (typeof decodedToken === 'undefined') {
131
- return '';
132
- }
133
- const decodedBytes = (0, utils_1.splitToken)(decodedToken).map((x) => byteDecoder.get(x));
134
- return textDecoder.decode(new Uint8Array(decodedBytes), {
135
- stream: true,
136
- });
137
- }
138
- exports.decodeToken = decodeToken;
139
- const HIGH_SURROGATE_START = 55296;
140
- const HIGH_SURROGATE_END = 56319;
141
- function endsWithIncompleteUtfPairSurrogate(string) {
142
- if (string.length === 0)
143
- return false;
144
- // Check if the last character is a high surrogate
145
- const lastCharCode = string.charCodeAt(string.length - 1);
146
- return (lastCharCode >= HIGH_SURROGATE_START && lastCharCode <= HIGH_SURROGATE_END);
147
- }
148
- exports.endsWithIncompleteUtfPairSurrogate = endsWithIncompleteUtfPairSurrogate;
149
- function* decodeGenerator(tokens) {
150
- let buffer = '';
151
- for (const token of tokens) {
152
- buffer += decodeToken(token);
153
- if (buffer.length === 0 || endsWithIncompleteUtfPairSurrogate(buffer)) {
154
- // Keep the high surrogate in the buffer and continue with the next token
155
- // eslint-disable-next-line no-continue
156
- continue;
157
- }
158
- else {
159
- yield buffer;
160
- // reset buffer
161
- buffer = '';
162
- }
163
- }
164
- // Yield any remaining characters in the buffer
165
- if (buffer.length > 0) {
166
- yield buffer;
167
- }
168
- }
169
- exports.decodeGenerator = decodeGenerator;
170
- /**
171
- * Decode tokens asynchronously and yield the decoded strings, one by one.
172
- * Will not yield for tokens that include a high surrogate, but wait for the next token.
173
- * @param {AsyncIterable<number>} tokens
174
- * @returns {AsyncGenerator<string, void, undefined>}
175
- */
176
- async function* decodeAsyncGenerator(tokens) {
177
- let buffer = '';
178
- for await (const token of tokens) {
179
- buffer += decodeToken(token);
180
- if (buffer.length === 0 || endsWithIncompleteUtfPairSurrogate(buffer)) {
181
- // Keep the high surrogate in the buffer and continue with the next token
182
- // eslint-disable-next-line no-continue
183
- continue;
184
- }
185
- else {
186
- yield buffer;
187
- // reset buffer
188
- buffer = '';
189
- }
190
- }
191
- // Yield any remaining characters in the buffer
192
- if (buffer.length > 0) {
193
- yield buffer;
194
- }
195
- }
196
- exports.decodeAsyncGenerator = decodeAsyncGenerator;
197
- function decode(tokens) {
198
- return [...decodeGenerator(tokens)].join('');
199
- }
200
- exports.decode = decode;
201
- //# sourceMappingURL=encoder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"encoder.js","sourceRoot":"","sources":["../src/encoder.ts"],"names":[],"mappings":"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"}
@@ -1,86 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- /* eslint-disable compat/compat */
4
- const encoder_1 = require("./encoder");
5
- describe('basic functionality', () => {
6
- it('empty string', () => {
7
- const str = '';
8
- expect((0, encoder_1.encode)(str)).toEqual([]);
9
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
10
- expect((0, encoder_1.isWithinTokenLimit)(str, 0)).toBe(0);
11
- expect((0, encoder_1.isWithinTokenLimit)(str, 3)).toBe(0);
12
- });
13
- it('space', () => {
14
- const str = ' ';
15
- expect((0, encoder_1.encode)(str)).toEqual([220]);
16
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
17
- expect((0, encoder_1.isWithinTokenLimit)(str, 3)).toBe(1);
18
- expect((0, encoder_1.isWithinTokenLimit)(str, 0)).toBe(false);
19
- });
20
- it('tab', () => {
21
- const str = '\t';
22
- expect((0, encoder_1.encode)(str)).toEqual([197]);
23
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
24
- });
25
- it('simple text', () => {
26
- const str = 'This is some text';
27
- expect((0, encoder_1.encode)(str)).toEqual([1212, 318, 617, 2420]);
28
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
29
- expect((0, encoder_1.isWithinTokenLimit)(str, 3)).toBe(false);
30
- expect((0, encoder_1.isWithinTokenLimit)(str, 5)).toBe(4);
31
- });
32
- it('multi-token word', () => {
33
- const str = 'indivisible';
34
- expect((0, encoder_1.encode)(str)).toEqual([521, 452, 12843]);
35
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
36
- expect((0, encoder_1.isWithinTokenLimit)(str, 3)).toBe(3);
37
- });
38
- const helloWorldTokens = [31373, 50169, 233, 995, 12520, 234, 235];
39
- it('emojis', () => {
40
- const str = 'hello 👋 world 🌍';
41
- expect((0, encoder_1.encode)(str)).toEqual(helloWorldTokens);
42
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
43
- expect((0, encoder_1.isWithinTokenLimit)(str, 4)).toBe(false);
44
- expect((0, encoder_1.isWithinTokenLimit)(str, 400)).toBe(7);
45
- });
46
- it('decode token-by-token via generator', () => {
47
- const generator = (0, encoder_1.decodeGenerator)(helloWorldTokens);
48
- expect(generator.next().value).toBe('hello');
49
- expect(generator.next().value).toBe(' ');
50
- expect(generator.next().value).toBe('👋');
51
- expect(generator.next().value).toBe(' world');
52
- expect(generator.next().value).toBe(' ');
53
- expect(generator.next().value).toBe('🌍');
54
- });
55
- async function* getHelloWorldTokensAsync() {
56
- for (const token of helloWorldTokens) {
57
- // eslint-disable-next-line no-await-in-loop
58
- yield await Promise.resolve(token);
59
- }
60
- }
61
- it('decode token-by-token via async generator', async () => {
62
- const generator = (0, encoder_1.decodeAsyncGenerator)(getHelloWorldTokensAsync());
63
- const decoded = ['hello', ' ', '👋', ' world', ' ', '🌍'];
64
- for await (const value of generator) {
65
- expect(value).toEqual(decoded.shift());
66
- }
67
- });
68
- it('properties of Object', () => {
69
- const str = 'toString constructor hasOwnProperty valueOf';
70
- expect((0, encoder_1.encode)(str)).toEqual([
71
- 1462, 10100, 23772, 468, 23858, 21746, 1988, 5189,
72
- ]);
73
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
74
- });
75
- it('text with commas', () => {
76
- const str = 'hello, I am a text, and I have commas. a,b,c';
77
- expect((0, encoder_1.decode)((0, encoder_1.encode)(str))).toEqual(str);
78
- expect((0, encoder_1.encode)(str)).toStrictEqual([
79
- 31373, 11, 314, 716, 257, 2420, 11, 290, 314, 423, 725, 292, 13, 257,
80
- 11, 65, 11, 66,
81
- ]);
82
- expect((0, encoder_1.isWithinTokenLimit)(str, 15)).toBe(false);
83
- expect((0, encoder_1.isWithinTokenLimit)(str, 300)).toBe(18);
84
- });
85
- });
86
- //# sourceMappingURL=encoder.test.js.map