@gringow/gringow 0.1.2 → 0.1.3
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 +82 -40
- package/dist/browser.d.mts +2 -1
- package/dist/browser.mjs +61 -4
- package/dist/config.mjs +3 -3
- package/dist/config.test.mjs +50 -67
- package/dist/{data/create-cache-id.d.mts → create-cache-id.d.mts} +2 -2
- package/dist/create-cache-id.mjs +54 -0
- package/dist/create-cache-id.test.d.mts +2 -0
- package/dist/create-cache-id.test.mjs +18464 -0
- package/dist/data/check-cache.d.mts +1 -1
- package/dist/data/check-cache.mjs +12 -7
- package/dist/data/clear-cache.mjs +12 -7
- package/dist/data/create-cache-dir.mjs +3 -3
- package/dist/data/delete-cache-item.d.mts +1 -1
- package/dist/data/delete-cache-item.mjs +12 -7
- package/dist/data/get-cache.mjs +3 -3
- package/dist/data/get-or-create-cache.d.mts +1 -1
- package/dist/data/get-or-create-cache.mjs +12 -7
- package/dist/data/md5.d.mts +13 -0
- package/dist/data/md5.mjs +47 -0
- package/dist/data/md5.test.d.mts +2 -0
- package/dist/data/md5.test.mjs +18457 -0
- package/dist/data/save-cache.d.mts +2 -2
- package/dist/data/save-cache.mjs +12 -7
- package/dist/data/write-cache-to-disk.d.mts +1 -1
- package/dist/data/write-cache-to-disk.mjs +12 -7
- package/dist/flat-template-string.test.mjs +10 -10
- package/dist/gringow.d.mts +1 -1
- package/dist/gringow.mjs +98 -35
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +98 -35
- package/dist/interpolate-template.d.mts +3 -0
- package/dist/interpolate-template.mjs +14 -0
- package/dist/io/anthropic/ask.mjs +3 -3
- package/dist/io/anthropic/commit-response.d.mts +1 -1
- package/dist/io/anthropic/index.d.mts +1 -1
- package/dist/io/anthropic/index.mjs +3 -3
- package/dist/io/anthropic/parse.d.mts +1 -1
- package/dist/io/ask-llm.d.mts +1 -1
- package/dist/io/ask-llm.mjs +36 -25
- package/dist/io/gemini/ask.mjs +36 -25
- package/dist/io/gemini/index.d.mts +1 -1
- package/dist/io/gemini/index.mjs +36 -25
- package/dist/io/gemini/parse.d.mts +1 -1
- package/dist/io/huggingface/ask.d.mts +1 -1
- package/dist/io/huggingface/ask.mjs +3 -3
- package/dist/io/huggingface/commit-response.d.mts +1 -1
- package/dist/io/huggingface/index.d.mts +1 -1
- package/dist/io/huggingface/index.mjs +3 -3
- package/dist/io/huggingface/parse.d.mts +1 -1
- package/dist/logger.test.mjs +10 -10
- package/dist/types/index.d.mts +1 -1
- package/package.json +10 -10
- package/dist/data/create-cache-id.mjs +0 -10
package/README.md
CHANGED
|
@@ -15,73 +15,115 @@ yarn add @gringow/gringow
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
import Gringow from '@gringow/gringow'
|
|
18
|
+
import Gringow, { rebuild } from '@gringow/gringow'
|
|
19
19
|
|
|
20
20
|
// Simple string translation
|
|
21
|
-
const
|
|
22
|
-
console.log(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
21
|
+
const { cacheId, translation } = await Gringow`Hello world`
|
|
22
|
+
console.log(cacheId) // deterministic cache ID created from the flattened string
|
|
23
|
+
console.log(translation.translation) // { "pt-BR": "Olá mundo", "fr-CA": "Bonjour le monde" }
|
|
24
|
+
|
|
25
|
+
// Template string translation (values are flattened before hashing)
|
|
26
|
+
const name = 'John'
|
|
27
|
+
const { translation: hiJohn } = await Gringow`Hello ${name}`
|
|
28
|
+
console.log(hiJohn.translation) // { "pt-BR": "Olá John", "fr-CA": "Bonjour John" }
|
|
29
|
+
|
|
30
|
+
// Re-run an existing cache entry against the configured LLM
|
|
31
|
+
const refreshed = await rebuild(cacheId)
|
|
32
|
+
console.log(refreshed.translation.translation)
|
|
28
33
|
```
|
|
29
34
|
|
|
35
|
+
Gringow always returns a `{ cacheId, translation }` object. The `translation` payload can include optional
|
|
36
|
+
`prepend`/`append` strings when you use custom prompts.
|
|
37
|
+
|
|
30
38
|
## Configuration
|
|
31
39
|
|
|
32
|
-
|
|
40
|
+
Gringow loads configuration via `cosmiconfig` using the `gringow` namespace. You can place any of the supported
|
|
41
|
+
formats in your project root (e.g. `gringow.config.js`, `gringow.config.mjs`, `gringow.config.json`). Missing fields
|
|
42
|
+
are merged with the defaults below and validated with Zod.
|
|
33
43
|
|
|
34
|
-
```
|
|
44
|
+
```js
|
|
45
|
+
// gringow.config.js
|
|
35
46
|
export default {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
debug: false,
|
|
48
|
+
log: { level: 'debug' },
|
|
49
|
+
cache: {
|
|
50
|
+
dir: './gringow',
|
|
51
|
+
file: 'gringow.json',
|
|
52
|
+
prefix: 'grw',
|
|
53
|
+
write: true, // set to false to skip writing to disk
|
|
41
54
|
},
|
|
42
55
|
keys: {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
56
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
|
57
|
+
geminiApiKey: process.env.GEMINI_API_KEY,
|
|
58
|
+
},
|
|
59
|
+
sourceLanguage: 'en-US',
|
|
60
|
+
languages: ['pt-BR', 'fr-CA'],
|
|
61
|
+
llm: {
|
|
62
|
+
choice: 'huggingface', // 'huggingface' | 'anthropic' | 'gemini'
|
|
63
|
+
model: 'Xenova/nllb-200-distilled-600M',
|
|
64
|
+
temperature: 1.0,
|
|
65
|
+
sleep: 0,
|
|
66
|
+
// Prompt shaping (all optional)
|
|
67
|
+
prePrompt: undefined,
|
|
68
|
+
postPrompt: undefined,
|
|
69
|
+
prePromptAppend: undefined,
|
|
70
|
+
postPromptPrepend: undefined,
|
|
71
|
+
prePromptReplace: undefined,
|
|
72
|
+
postPromptReplace: undefined,
|
|
73
|
+
},
|
|
74
|
+
// Files scanned by the Vite/Next.js plugins when building caches
|
|
75
|
+
globby: './src/**/*.{js,jsx,ts,tsx}',
|
|
46
76
|
}
|
|
47
77
|
```
|
|
48
78
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **Hugging Face** (default): Local models, no API key required
|
|
52
|
-
- **Anthropic**: Requires `anthropicApiKey`
|
|
53
|
-
- **Gemini**: Requires `geminiApiKey`
|
|
79
|
+
> For `anthropic` or `gemini`, the corresponding API key **must** be present or config validation will fail.
|
|
54
80
|
|
|
55
|
-
##
|
|
81
|
+
## LLM Providers
|
|
56
82
|
|
|
57
|
-
|
|
83
|
+
- **Hugging Face** (default): Runs local models, no API key required.
|
|
84
|
+
- **Anthropic**: Requires `keys.anthropicApiKey`.
|
|
85
|
+
- **Gemini**: Requires `keys.geminiApiKey`.
|
|
58
86
|
|
|
59
|
-
|
|
87
|
+
## API surface
|
|
60
88
|
|
|
61
|
-
|
|
62
|
-
- `
|
|
63
|
-
- `
|
|
89
|
+
- `default export Gringow(strings, ...values)` — translate a string or tagged template. Returns a `Promise<GringowResponse>`.
|
|
90
|
+
- `rebuild(cacheId)` — re-asks the configured LLM for a cached entry and writes it back when `cache.write` is true.
|
|
91
|
+
- Cache helpers: `checkCache`, `getCache`, `getOrCreateCache`, `writeCacheToDisk`, `deleteCacheItem`, `clearCache`.
|
|
92
|
+
- Utilities: `createCacheId`, `flatTemplateString`, `interpolateTemplate` (browser build), `awaitedConfig`, `isLocalConfigFound`, `getConfigSource`.
|
|
64
93
|
|
|
65
|
-
|
|
94
|
+
```ts
|
|
95
|
+
type GringowTranslation = Record<string, string>
|
|
66
96
|
|
|
67
|
-
|
|
97
|
+
type GringowCacheItem = {
|
|
98
|
+
original: string
|
|
99
|
+
translation: GringowTranslation
|
|
100
|
+
append?: string
|
|
101
|
+
prepend?: string
|
|
102
|
+
rebuild?: boolean
|
|
103
|
+
}
|
|
68
104
|
|
|
69
|
-
```typescript
|
|
70
105
|
type GringowResponse = {
|
|
71
106
|
cacheId: string
|
|
72
107
|
translation: GringowCacheItem
|
|
73
108
|
}
|
|
109
|
+
```
|
|
74
110
|
|
|
75
|
-
|
|
76
|
-
original: string
|
|
77
|
-
translation: GringowTranslation
|
|
78
|
-
}
|
|
111
|
+
## Development
|
|
79
112
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
113
|
+
```bash
|
|
114
|
+
pnpm install
|
|
115
|
+
pnpm run build # builds the package
|
|
116
|
+
pnpm run test # vitest suite
|
|
83
117
|
```
|
|
84
118
|
|
|
85
119
|
## License
|
|
86
120
|
|
|
87
|
-
MIT
|
|
121
|
+
MIT
|
|
122
|
+
|
|
123
|
+
## Related Packages (npm)
|
|
124
|
+
|
|
125
|
+
- [@gringow/gringow-cli](https://www.npmjs.com/package/@gringow/gringow-cli) - Command-line interface
|
|
126
|
+
- [@gringow/gringow-shadow](https://www.npmjs.com/package/@gringow/gringow-shadow) - Web Component layer powering the React bindings
|
|
127
|
+
- [@gringow/gringow-react](https://www.npmjs.com/package/@gringow/gringow-react) - React bindings
|
|
128
|
+
- [@gringow/gringow-vite](https://www.npmjs.com/package/@gringow/gringow-vite) - Vite plugin
|
|
129
|
+
- [@gringow/gringow-nextjs](https://www.npmjs.com/package/@gringow/gringow-nextjs) - Experimental Next.js plugin
|
package/dist/browser.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { createCacheId } from './
|
|
1
|
+
export { createCacheId } from './create-cache-id.mjs';
|
|
2
2
|
export { flatTemplateString } from './flat-template-string.mjs';
|
|
3
|
+
export { interpolateTemplate } from './interpolate-template.mjs';
|
|
3
4
|
|
|
4
5
|
declare const GRINGOW_IO_URL = "https://gringow.io";
|
|
5
6
|
|
package/dist/browser.mjs
CHANGED
|
@@ -1,8 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
// src/data/md5.ts
|
|
2
|
+
var INITIAL_STATE = [1831565813, 461845907, 2246822507, 3266489909];
|
|
3
|
+
var MULTIPLIERS = [668265261, 374761393, 2654435769, 2496678331];
|
|
4
|
+
var AVA_MULT1 = 2146121005;
|
|
5
|
+
var AVA_MULT2 = 2221713035;
|
|
6
|
+
function seedState(input) {
|
|
7
|
+
const state = [...INITIAL_STATE];
|
|
8
|
+
for (const char of input) {
|
|
9
|
+
const codePoint = char.codePointAt(0) ?? 0;
|
|
10
|
+
for (let i = 0; i < state.length; i++) {
|
|
11
|
+
state[i] = Math.imul(state[i] ^ codePoint, MULTIPLIERS[i]);
|
|
12
|
+
state[i] = rotateLeft(state[i], (i + 1) * 3);
|
|
13
|
+
}
|
|
14
|
+
state[0] ^= state[3] >>> 11;
|
|
15
|
+
state[1] ^= state[0] << 7;
|
|
16
|
+
state[2] ^= state[1] >>> 13;
|
|
17
|
+
state[3] ^= state[2] << 5;
|
|
18
|
+
}
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
function rotateLeft(value, shift) {
|
|
22
|
+
return value << shift | value >>> 32 - shift;
|
|
23
|
+
}
|
|
24
|
+
function avalanche(value) {
|
|
25
|
+
value ^= value >>> 16;
|
|
26
|
+
value = Math.imul(value, AVA_MULT1);
|
|
27
|
+
value ^= value >>> 15;
|
|
28
|
+
value = Math.imul(value, AVA_MULT2);
|
|
29
|
+
value ^= value >>> 16;
|
|
30
|
+
return value >>> 0;
|
|
31
|
+
}
|
|
32
|
+
function toHex(value) {
|
|
33
|
+
return (value >>> 0).toString(16).padStart(8, "0");
|
|
34
|
+
}
|
|
35
|
+
function mixState([h1, h2, h3, h4]) {
|
|
36
|
+
h1 = avalanche(h1 ^ h3);
|
|
37
|
+
h2 = avalanche(h2 ^ h4);
|
|
38
|
+
h3 = avalanche(h3 ^ h1);
|
|
39
|
+
h4 = avalanche(h4 ^ h2);
|
|
40
|
+
return [h1, h2, h3, h4];
|
|
41
|
+
}
|
|
42
|
+
function md5(input) {
|
|
43
|
+
const state = mixState(seedState(input));
|
|
44
|
+
return state.map(toHex).join("");
|
|
45
|
+
}
|
|
2
46
|
|
|
3
|
-
// src/
|
|
47
|
+
// src/create-cache-id.ts
|
|
4
48
|
function createCacheId(text) {
|
|
5
|
-
const hexHash =
|
|
49
|
+
const hexHash = md5(text);
|
|
6
50
|
const cacheId = `gid_${hexHash}`;
|
|
7
51
|
return cacheId;
|
|
8
52
|
}
|
|
@@ -22,7 +66,20 @@ function flatTemplateString(givenStrings, givenValues) {
|
|
|
22
66
|
return flatted;
|
|
23
67
|
}
|
|
24
68
|
|
|
69
|
+
// src/interpolate-template.ts
|
|
70
|
+
function interpolateTemplate(template, values) {
|
|
71
|
+
if (!values || values.length === 0) return template;
|
|
72
|
+
let valueIndex = 0;
|
|
73
|
+
return template.replace(/\$\{[^}]*\}/g, () => {
|
|
74
|
+
if (valueIndex < values.length) {
|
|
75
|
+
const value = values[valueIndex++];
|
|
76
|
+
return value === null || value === void 0 ? "" : String(value);
|
|
77
|
+
}
|
|
78
|
+
return "";
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
25
82
|
// src/browser.ts
|
|
26
83
|
var GRINGOW_IO_URL = "https://gringow.io";
|
|
27
84
|
|
|
28
|
-
export { GRINGOW_IO_URL, createCacheId, flatTemplateString };
|
|
85
|
+
export { GRINGOW_IO_URL, createCacheId, flatTemplateString, interpolateTemplate };
|
package/dist/config.mjs
CHANGED
|
@@ -107,9 +107,9 @@ async function loadUserConfig() {
|
|
|
107
107
|
var awaitedConfig = loadUserConfig();
|
|
108
108
|
function defaultPrePrompt(config, extraInstructions) {
|
|
109
109
|
return `
|
|
110
|
-
You are a translation generator.
|
|
110
|
+
You are a ultimate translation generator server api.
|
|
111
111
|
|
|
112
|
-
Your task is to output **only one valid JSON object**, with **no text, explanations, or formatting
|
|
112
|
+
Your task is to translate a given text and output **only one valid JSON object**, with **no text, explanations, or formatting than the JSON**.
|
|
113
113
|
|
|
114
114
|
Follow these rules strictly:
|
|
115
115
|
|
|
@@ -119,7 +119,7 @@ Follow these rules strictly:
|
|
|
119
119
|
- Apply these creatively but **without altering the meaning or punctuation** of the original text.
|
|
120
120
|
3. Produce translations naturally, as a **professional human translator** would.
|
|
121
121
|
4. Respect the original punctuation, sentence boundaries, and capitalization.
|
|
122
|
-
5. Consider only the following target languages: ${(config?.languages ? config.languages : []).join(", ")}.
|
|
122
|
+
5. Consider only the following target languages: ${(config?.languages ? Array.from(/* @__PURE__ */ new Set(["es-ES", ...config.languages, config.sourceLanguage])) : []).join(", ")}.
|
|
123
123
|
6. The final output must be a **valid JSON** following this exact schema:
|
|
124
124
|
|
|
125
125
|
{
|
package/dist/config.test.mjs
CHANGED
|
@@ -1392,7 +1392,7 @@ var require_utils = __commonJS({
|
|
|
1392
1392
|
// ../node_modules/.pnpm/expect-type@1.2.2/node_modules/expect-type/dist/index.js
|
|
1393
1393
|
var require_dist = __commonJS({
|
|
1394
1394
|
"../node_modules/.pnpm/expect-type@1.2.2/node_modules/expect-type/dist/index.js"(exports) {
|
|
1395
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m3, k2, k22) {
|
|
1395
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m3, k2, k22) {
|
|
1396
1396
|
if (k22 === void 0) k22 = k2;
|
|
1397
1397
|
var desc = Object.getOwnPropertyDescriptor(m3, k2);
|
|
1398
1398
|
if (!desc || ("get" in desc ? !m3.__esModule : desc.writable || desc.configurable)) {
|
|
@@ -1401,10 +1401,10 @@ var require_dist = __commonJS({
|
|
|
1401
1401
|
} };
|
|
1402
1402
|
}
|
|
1403
1403
|
Object.defineProperty(o, k22, desc);
|
|
1404
|
-
} : function(o, m3, k2, k22) {
|
|
1404
|
+
}) : (function(o, m3, k2, k22) {
|
|
1405
1405
|
if (k22 === void 0) k22 = k2;
|
|
1406
1406
|
o[k22] = m3[k2];
|
|
1407
|
-
});
|
|
1407
|
+
}));
|
|
1408
1408
|
var __exportStar = exports && exports.__exportStar || function(m3, exports2) {
|
|
1409
1409
|
for (var p4 in m3) if (p4 !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p4)) __createBinding(exports2, m3, p4);
|
|
1410
1410
|
};
|
|
@@ -13239,7 +13239,7 @@ function findTestFileStackTrace(error, each) {
|
|
|
13239
13239
|
globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
|
|
13240
13240
|
globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
|
|
13241
13241
|
|
|
13242
|
-
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.
|
|
13242
|
+
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.4_lightningcss@1.30.2_terser@5.44.1/node_modules/vitest/dist/chunks/utils.C8RiOc4B.js
|
|
13243
13243
|
var NAME_WORKER_STATE = "__vitest_worker__";
|
|
13244
13244
|
function getWorkerState() {
|
|
13245
13245
|
const workerState = globalThis[NAME_WORKER_STATE];
|
|
@@ -13299,7 +13299,7 @@ async function waitForImportsToResolve() {
|
|
|
13299
13299
|
await waitForImportsToResolve();
|
|
13300
13300
|
}
|
|
13301
13301
|
|
|
13302
|
-
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.
|
|
13302
|
+
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.4_lightningcss@1.30.2_terser@5.44.1/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js
|
|
13303
13303
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
13304
13304
|
function getDefaultExportFromCjs2(x2) {
|
|
13305
13305
|
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
@@ -15333,7 +15333,7 @@ var SnapshotClient = class {
|
|
|
15333
15333
|
}
|
|
15334
15334
|
};
|
|
15335
15335
|
|
|
15336
|
-
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.
|
|
15336
|
+
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.4_lightningcss@1.30.2_terser@5.44.1/node_modules/vitest/dist/chunks/date.W2xKR2qe.js
|
|
15337
15337
|
var RealDate = Date;
|
|
15338
15338
|
var now2 = null;
|
|
15339
15339
|
var MockDate = class _MockDate extends RealDate {
|
|
@@ -15386,7 +15386,7 @@ function resetDate() {
|
|
|
15386
15386
|
globalThis.Date = RealDate;
|
|
15387
15387
|
}
|
|
15388
15388
|
|
|
15389
|
-
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.
|
|
15389
|
+
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.4_lightningcss@1.30.2_terser@5.44.1/node_modules/vitest/dist/chunks/vi.DgezovHB.js
|
|
15390
15390
|
var unsupported = [
|
|
15391
15391
|
// .poll is meant to retry matchers until they succeed, and
|
|
15392
15392
|
// snapshots will always succeed as long as the poll method doesn't thow an error
|
|
@@ -16215,7 +16215,7 @@ function requireTypeDetect() {
|
|
|
16215
16215
|
(function(module, exports) {
|
|
16216
16216
|
(function(global3, factory) {
|
|
16217
16217
|
module.exports = factory();
|
|
16218
|
-
})(typeDetect, function() {
|
|
16218
|
+
})(typeDetect, (function() {
|
|
16219
16219
|
var promiseExists = typeof Promise === "function";
|
|
16220
16220
|
var globalObject = typeof self === "object" ? self : commonjsGlobal;
|
|
16221
16221
|
var symbolExists = typeof Symbol !== "undefined";
|
|
@@ -16324,7 +16324,7 @@ function requireTypeDetect() {
|
|
|
16324
16324
|
return Object.prototype.toString.call(obj).slice(toStringLeftSliceLength, toStringRightSliceLength);
|
|
16325
16325
|
}
|
|
16326
16326
|
return typeDetect2;
|
|
16327
|
-
});
|
|
16327
|
+
}));
|
|
16328
16328
|
})(typeDetect$1);
|
|
16329
16329
|
return typeDetect$1.exports;
|
|
16330
16330
|
}
|
|
@@ -18118,7 +18118,7 @@ function getImporter(name) {
|
|
|
18118
18118
|
return stack?.file || "";
|
|
18119
18119
|
}
|
|
18120
18120
|
|
|
18121
|
-
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.
|
|
18121
|
+
// ../node_modules/.pnpm/vitest@2.1.9_@types+node@22.16.4_lightningcss@1.30.2_terser@5.44.1/node_modules/vitest/dist/index.js
|
|
18122
18122
|
__toESM(require_dist(), 1);
|
|
18123
18123
|
|
|
18124
18124
|
// src/constants/default-config.ts
|
|
@@ -18218,9 +18218,9 @@ async function loadUserConfig() {
|
|
|
18218
18218
|
loadUserConfig();
|
|
18219
18219
|
function defaultPrePrompt(config2, extraInstructions) {
|
|
18220
18220
|
return `
|
|
18221
|
-
You are a translation generator.
|
|
18221
|
+
You are a ultimate translation generator server api.
|
|
18222
18222
|
|
|
18223
|
-
Your task is to output **only one valid JSON object**, with **no text, explanations, or formatting
|
|
18223
|
+
Your task is to translate a given text and output **only one valid JSON object**, with **no text, explanations, or formatting than the JSON**.
|
|
18224
18224
|
|
|
18225
18225
|
Follow these rules strictly:
|
|
18226
18226
|
|
|
@@ -18230,7 +18230,7 @@ Follow these rules strictly:
|
|
|
18230
18230
|
- Apply these creatively but **without altering the meaning or punctuation** of the original text.
|
|
18231
18231
|
3. Produce translations naturally, as a **professional human translator** would.
|
|
18232
18232
|
4. Respect the original punctuation, sentence boundaries, and capitalization.
|
|
18233
|
-
5. Consider only the following target languages: ${(config2?.languages ? config2.languages : []).join(", ")}.
|
|
18233
|
+
5. Consider only the following target languages: ${(config2?.languages ? Array.from(/* @__PURE__ */ new Set(["es-ES", ...config2.languages, config2.sourceLanguage])) : []).join(", ")}.
|
|
18234
18234
|
6. The final output must be a **valid JSON** following this exact schema:
|
|
18235
18235
|
|
|
18236
18236
|
{
|
|
@@ -18273,26 +18273,27 @@ function postPrompt(config2, prepend, replace) {
|
|
|
18273
18273
|
// src/config.test.ts
|
|
18274
18274
|
describe("config", () => {
|
|
18275
18275
|
describe("defaultPrePrompt", () => {
|
|
18276
|
-
it("should
|
|
18276
|
+
it("should describe translation task with configured languages", () => {
|
|
18277
18277
|
const config2 = {
|
|
18278
18278
|
...defaultConfig,
|
|
18279
18279
|
languages: ["pt-BR", "fr-CA", "es-ES"]
|
|
18280
18280
|
};
|
|
18281
18281
|
const result2 = defaultPrePrompt(config2);
|
|
18282
|
+
globalExpect(result2).toContain("You are a translation generator.");
|
|
18283
|
+
globalExpect(result2).toContain("Your task is to output **only one valid JSON object**");
|
|
18282
18284
|
globalExpect(result2).toContain("pt-BR, fr-CA, es-ES");
|
|
18283
|
-
globalExpect(result2).toContain("
|
|
18284
|
-
globalExpect(result2).toContain("
|
|
18285
|
-
globalExpect(result2).toContain('"original"');
|
|
18286
|
-
globalExpect(result2).toContain('"translation"');
|
|
18285
|
+
globalExpect(result2).toContain('"original": "<original input text>"');
|
|
18286
|
+
globalExpect(result2).toContain('"translation": {');
|
|
18287
18287
|
});
|
|
18288
|
-
it("should include
|
|
18288
|
+
it("should include extraInstructions block when provided", () => {
|
|
18289
18289
|
const config2 = {
|
|
18290
18290
|
...defaultConfig,
|
|
18291
18291
|
languages: ["pt-BR"]
|
|
18292
18292
|
};
|
|
18293
|
-
const result2 = defaultPrePrompt(config2);
|
|
18294
|
-
globalExpect(result2).toContain(
|
|
18295
|
-
globalExpect(result2).toContain(
|
|
18293
|
+
const result2 = defaultPrePrompt(config2, "Use pirate voice");
|
|
18294
|
+
globalExpect(result2).toContain("Now, using these instructions and applying the following extra parameters:");
|
|
18295
|
+
globalExpect(result2).toContain("extraInstructions: Use pirate voice");
|
|
18296
|
+
globalExpect(result2).toContain("Translate the following text faithfully:");
|
|
18296
18297
|
});
|
|
18297
18298
|
});
|
|
18298
18299
|
describe("defaultPostPrompt", () => {
|
|
@@ -18301,87 +18302,69 @@ describe("config", () => {
|
|
|
18301
18302
|
...defaultConfig
|
|
18302
18303
|
});
|
|
18303
18304
|
const result2 = defaultPostPrompt();
|
|
18304
|
-
globalExpect(result2).
|
|
18305
|
-
globalExpect(result2).toContain("[/POST-MESSAGE]");
|
|
18306
|
-
globalExpect(result2).toContain("DO NOT WRAP IT IN A CODE BLOCK");
|
|
18307
|
-
globalExpect(result2).toContain("FIRST CHARACTER MUST BE A {");
|
|
18308
|
-
globalExpect(result2).toContain("LAST CHARACTER MUST BE A }");
|
|
18305
|
+
globalExpect(result2).toBe("");
|
|
18309
18306
|
});
|
|
18310
18307
|
});
|
|
18311
18308
|
describe("prePrompt", () => {
|
|
18312
18309
|
it("should use prePromptReplace when provided", () => {
|
|
18313
18310
|
const config2 = {
|
|
18314
|
-
...defaultConfig
|
|
18315
|
-
llm: {
|
|
18316
|
-
...defaultConfig.llm}
|
|
18311
|
+
...defaultConfig
|
|
18317
18312
|
};
|
|
18318
|
-
const result2 = prePrompt(config2);
|
|
18313
|
+
const result2 = prePrompt(config2, void 0, "Custom pre-prompt");
|
|
18319
18314
|
globalExpect(result2).toBe("Custom pre-prompt");
|
|
18320
18315
|
});
|
|
18321
18316
|
it("should use prePromptAppend when provided", () => {
|
|
18322
18317
|
const config2 = {
|
|
18323
|
-
...defaultConfig
|
|
18324
|
-
llm: {
|
|
18325
|
-
...defaultConfig.llm}
|
|
18318
|
+
...defaultConfig
|
|
18326
18319
|
};
|
|
18327
|
-
const result2 = prePrompt(config2);
|
|
18328
|
-
globalExpect(result2).toContain("Additional instructions");
|
|
18329
|
-
globalExpect(result2).toContain("
|
|
18320
|
+
const result2 = prePrompt(config2, "Additional instructions");
|
|
18321
|
+
globalExpect(result2).toContain("extraInstructions: Additional instructions");
|
|
18322
|
+
globalExpect(result2).toContain("You are a translation generator.");
|
|
18330
18323
|
});
|
|
18331
18324
|
it("should use prePromptReplace and prePromptAppend together", () => {
|
|
18332
18325
|
const config2 = {
|
|
18333
|
-
...defaultConfig
|
|
18334
|
-
llm: {
|
|
18335
|
-
...defaultConfig.llm}
|
|
18326
|
+
...defaultConfig
|
|
18336
18327
|
};
|
|
18337
|
-
const result2 = prePrompt(config2);
|
|
18338
|
-
globalExpect(result2).toBe("Custom pre-prompt
|
|
18328
|
+
const result2 = prePrompt(config2, "Additional instructions", "Custom pre-prompt");
|
|
18329
|
+
globalExpect(result2).toBe("Custom pre-prompt");
|
|
18339
18330
|
});
|
|
18340
18331
|
it("should use default prompt when no customization is provided", () => {
|
|
18341
18332
|
const config2 = {
|
|
18342
18333
|
...defaultConfig
|
|
18343
18334
|
};
|
|
18344
18335
|
const result2 = prePrompt(config2);
|
|
18345
|
-
globalExpect(result2).toContain("
|
|
18346
|
-
globalExpect(result2).toContain("
|
|
18336
|
+
globalExpect(result2).toContain("You are a translation generator.");
|
|
18337
|
+
globalExpect(result2).toContain("Translate the following text faithfully:");
|
|
18347
18338
|
});
|
|
18348
18339
|
});
|
|
18349
18340
|
describe("postPrompt", () => {
|
|
18350
18341
|
it("should use postPromptReplace when provided", () => {
|
|
18351
|
-
|
|
18352
|
-
...defaultConfig
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
});
|
|
18356
|
-
const result2 = postPrompt();
|
|
18342
|
+
const config2 = {
|
|
18343
|
+
...defaultConfig
|
|
18344
|
+
};
|
|
18345
|
+
const result2 = postPrompt(config2, void 0, "Custom post-prompt");
|
|
18357
18346
|
globalExpect(result2).toBe("Custom post-prompt");
|
|
18358
18347
|
});
|
|
18359
18348
|
it("should use postPromptPrepend when provided", () => {
|
|
18360
|
-
|
|
18361
|
-
...defaultConfig
|
|
18362
|
-
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
const result2 = postPrompt();
|
|
18366
|
-
globalExpect(result2).toContain("Additional post instructions");
|
|
18367
|
-
globalExpect(result2).toContain("[POST-MESSAGE]");
|
|
18349
|
+
const config2 = {
|
|
18350
|
+
...defaultConfig
|
|
18351
|
+
};
|
|
18352
|
+
const result2 = postPrompt(config2, "Additional post instructions");
|
|
18353
|
+
globalExpect(result2).toBe("[SPECIFIC_INPUTS] Additional post instructions [/SPECIFIC_INPUTS]");
|
|
18368
18354
|
});
|
|
18369
18355
|
it("should use postPromptReplace and postPromptPrepend together", () => {
|
|
18370
|
-
|
|
18371
|
-
...defaultConfig
|
|
18372
|
-
|
|
18373
|
-
|
|
18374
|
-
|
|
18375
|
-
const result2 = postPrompt();
|
|
18376
|
-
globalExpect(result2).toBe("Additional post instructions Custom post-prompt");
|
|
18356
|
+
const config2 = {
|
|
18357
|
+
...defaultConfig
|
|
18358
|
+
};
|
|
18359
|
+
const result2 = postPrompt(config2, "Additional post instructions", "Custom post-prompt");
|
|
18360
|
+
globalExpect(result2).toBe("[SPECIFIC_INPUTS] Additional post instructions [/SPECIFIC_INPUTS] Custom post-prompt");
|
|
18377
18361
|
});
|
|
18378
18362
|
it("should use default prompt when no customization is provided", () => {
|
|
18379
18363
|
({
|
|
18380
18364
|
...defaultConfig
|
|
18381
18365
|
});
|
|
18382
18366
|
const result2 = postPrompt();
|
|
18383
|
-
globalExpect(result2).
|
|
18384
|
-
globalExpect(result2).toContain("[/POST-MESSAGE]");
|
|
18367
|
+
globalExpect(result2).toBe("");
|
|
18385
18368
|
});
|
|
18386
18369
|
});
|
|
18387
18370
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Creates a
|
|
2
|
+
* Creates a stable cache ID for a given text using a deterministic hash
|
|
3
3
|
*
|
|
4
4
|
* @param text - The text string to create a cache ID for
|
|
5
|
-
* @returns
|
|
5
|
+
* @returns Deterministic hash of the text as a hex string
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* const id = createCacheId("my text")
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/data/md5.ts
|
|
2
|
+
var INITIAL_STATE = [1831565813, 461845907, 2246822507, 3266489909];
|
|
3
|
+
var MULTIPLIERS = [668265261, 374761393, 2654435769, 2496678331];
|
|
4
|
+
var AVA_MULT1 = 2146121005;
|
|
5
|
+
var AVA_MULT2 = 2221713035;
|
|
6
|
+
function seedState(input) {
|
|
7
|
+
const state = [...INITIAL_STATE];
|
|
8
|
+
for (const char of input) {
|
|
9
|
+
const codePoint = char.codePointAt(0) ?? 0;
|
|
10
|
+
for (let i = 0; i < state.length; i++) {
|
|
11
|
+
state[i] = Math.imul(state[i] ^ codePoint, MULTIPLIERS[i]);
|
|
12
|
+
state[i] = rotateLeft(state[i], (i + 1) * 3);
|
|
13
|
+
}
|
|
14
|
+
state[0] ^= state[3] >>> 11;
|
|
15
|
+
state[1] ^= state[0] << 7;
|
|
16
|
+
state[2] ^= state[1] >>> 13;
|
|
17
|
+
state[3] ^= state[2] << 5;
|
|
18
|
+
}
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
function rotateLeft(value, shift) {
|
|
22
|
+
return value << shift | value >>> 32 - shift;
|
|
23
|
+
}
|
|
24
|
+
function avalanche(value) {
|
|
25
|
+
value ^= value >>> 16;
|
|
26
|
+
value = Math.imul(value, AVA_MULT1);
|
|
27
|
+
value ^= value >>> 15;
|
|
28
|
+
value = Math.imul(value, AVA_MULT2);
|
|
29
|
+
value ^= value >>> 16;
|
|
30
|
+
return value >>> 0;
|
|
31
|
+
}
|
|
32
|
+
function toHex(value) {
|
|
33
|
+
return (value >>> 0).toString(16).padStart(8, "0");
|
|
34
|
+
}
|
|
35
|
+
function mixState([h1, h2, h3, h4]) {
|
|
36
|
+
h1 = avalanche(h1 ^ h3);
|
|
37
|
+
h2 = avalanche(h2 ^ h4);
|
|
38
|
+
h3 = avalanche(h3 ^ h1);
|
|
39
|
+
h4 = avalanche(h4 ^ h2);
|
|
40
|
+
return [h1, h2, h3, h4];
|
|
41
|
+
}
|
|
42
|
+
function md5(input) {
|
|
43
|
+
const state = mixState(seedState(input));
|
|
44
|
+
return state.map(toHex).join("");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/create-cache-id.ts
|
|
48
|
+
function createCacheId(text) {
|
|
49
|
+
const hexHash = md5(text);
|
|
50
|
+
const cacheId = `gid_${hexHash}`;
|
|
51
|
+
return cacheId;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { createCacheId };
|