@promptbook/utils 0.102.0-11 → 0.102.0-16
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/esm/index.es.js +979 -2
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/color.index.d.ts +2 -0
- package/esm/typings/src/_packages/components.index.d.ts +4 -0
- package/esm/typings/src/_packages/core.index.d.ts +6 -0
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
- package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +4 -0
- package/esm/typings/src/book-components/Chat/save/_common/ChatSaveFormatDefinition.d.ts +43 -5
- package/esm/typings/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +6 -2
- package/esm/typings/src/book-components/Chat/save/index.d.ts +38 -8
- package/esm/typings/src/book-components/Chat/save/json/jsonSaveFormatDefinition.d.ts +6 -2
- package/esm/typings/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -1
- package/esm/typings/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +6 -2
- package/esm/typings/src/book-components/Chat/save/react/reactSaveFormatDefinition.d.ts +16 -0
- package/esm/typings/src/book-components/Chat/save/text/txtSaveFormatDefinition.d.ts +5 -1
- package/esm/typings/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
- package/esm/typings/src/book-components/icons/SaveIcon.d.ts +10 -0
- package/esm/typings/src/config.d.ts +26 -4
- package/esm/typings/src/utils/color/Color.d.ts +8 -0
- package/esm/typings/src/utils/color/operators/darken.d.ts +2 -1
- package/esm/typings/src/utils/color/operators/grayscale.d.ts +2 -1
- package/esm/typings/src/utils/color/operators/lighten.d.ts +2 -1
- package/esm/typings/src/utils/color/operators/mixWithColor.d.ts +2 -1
- package/esm/typings/src/utils/color/operators/saturate.d.ts +13 -0
- package/esm/typings/src/utils/serialization/serializeToPromptbookJavascript.d.ts +22 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +979 -1
- package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js
CHANGED
@@ -22,12 +22,901 @@
|
|
22
22
|
* @generated
|
23
23
|
* @see https://github.com/webgptorg/promptbook
|
24
24
|
*/
|
25
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.102.0-
|
25
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.102.0-16';
|
26
26
|
/**
|
27
27
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
28
28
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
29
29
|
*/
|
30
30
|
|
31
|
+
/**
|
32
|
+
* @private util of `@promptbook/color`
|
33
|
+
* @de
|
34
|
+
*/
|
35
|
+
class TakeChain {
|
36
|
+
constructor(value) {
|
37
|
+
this.value = value;
|
38
|
+
}
|
39
|
+
then(callback) {
|
40
|
+
const newValue = callback(this.value);
|
41
|
+
return take(newValue);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* A function that takes an initial value and returns a proxy object with chainable methods.
|
47
|
+
*
|
48
|
+
* @param {*} initialValue - The initial value.
|
49
|
+
* @returns {Proxy<WithTake<TValue>>} - A proxy object with a `take` method.
|
50
|
+
*
|
51
|
+
* @private util of `@promptbook/color`
|
52
|
+
* @deprecated [🤡] Use some better functional library instead of `TakeChain`
|
53
|
+
*/
|
54
|
+
function take(initialValue) {
|
55
|
+
if (initialValue instanceof TakeChain) {
|
56
|
+
return initialValue;
|
57
|
+
}
|
58
|
+
return new Proxy(new TakeChain(initialValue), {
|
59
|
+
get(target, property, receiver) {
|
60
|
+
if (Reflect.has(target, property)) {
|
61
|
+
return Reflect.get(target, property, receiver);
|
62
|
+
}
|
63
|
+
else if (Reflect.has(initialValue, property)) {
|
64
|
+
return Reflect.get(initialValue, property, receiver);
|
65
|
+
}
|
66
|
+
else {
|
67
|
+
return undefined;
|
68
|
+
}
|
69
|
+
},
|
70
|
+
});
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* 🎨 List of all 140 color names which are supported by CSS
|
75
|
+
*
|
76
|
+
* @public exported from `@promptbook/color`
|
77
|
+
*/
|
78
|
+
const CSS_COLORS = {
|
79
|
+
transparent: 'rgba(0,0,0,0)',
|
80
|
+
aliceblue: '#f0f8ff',
|
81
|
+
antiquewhite: '#faebd7',
|
82
|
+
aqua: '#00ffff',
|
83
|
+
aquamarine: '#7fffd4',
|
84
|
+
azure: '#f0ffff',
|
85
|
+
beige: '#f5f5dc',
|
86
|
+
bisque: '#ffe4c4',
|
87
|
+
black: '#000000',
|
88
|
+
blanchedalmond: '#ffebcd',
|
89
|
+
blue: '#0000ff',
|
90
|
+
blueviolet: '#8a2be2',
|
91
|
+
brown: '#a52a2a',
|
92
|
+
burlywood: '#deb887',
|
93
|
+
cadetblue: '#5f9ea0',
|
94
|
+
chartreuse: '#7fff00',
|
95
|
+
chocolate: '#d2691e',
|
96
|
+
coral: '#ff7f50',
|
97
|
+
cornflowerblue: '#6495ed',
|
98
|
+
cornsilk: '#fff8dc',
|
99
|
+
crimson: '#dc143c',
|
100
|
+
cyan: '#00ffff',
|
101
|
+
darkblue: '#00008b',
|
102
|
+
darkcyan: '#008b8b',
|
103
|
+
darkgoldenrod: '#b8860b',
|
104
|
+
darkgray: '#a9a9a9',
|
105
|
+
darkgrey: '#a9a9a9',
|
106
|
+
darkgreen: '#006400',
|
107
|
+
darkkhaki: '#bdb76b',
|
108
|
+
darkmagenta: '#8b008b',
|
109
|
+
darkolivegreen: '#556b2f',
|
110
|
+
darkorange: '#ff8c00',
|
111
|
+
darkorchid: '#9932cc',
|
112
|
+
darkred: '#8b0000',
|
113
|
+
darksalmon: '#e9967a',
|
114
|
+
darkseagreen: '#8fbc8f',
|
115
|
+
darkslateblue: '#483d8b',
|
116
|
+
darkslategray: '#2f4f4f',
|
117
|
+
darkslategrey: '#2f4f4f',
|
118
|
+
darkturquoise: '#00ced1',
|
119
|
+
darkviolet: '#9400d3',
|
120
|
+
deeppink: '#ff1493',
|
121
|
+
deepskyblue: '#00bfff',
|
122
|
+
dimgray: '#696969',
|
123
|
+
dimgrey: '#696969',
|
124
|
+
dodgerblue: '#1e90ff',
|
125
|
+
firebrick: '#b22222',
|
126
|
+
floralwhite: '#fffaf0',
|
127
|
+
forestgreen: '#228b22',
|
128
|
+
fuchsia: '#ff00ff',
|
129
|
+
gainsboro: '#dcdcdc',
|
130
|
+
ghostwhite: '#f8f8ff',
|
131
|
+
gold: '#ffd700',
|
132
|
+
goldenrod: '#daa520',
|
133
|
+
gray: '#808080',
|
134
|
+
grey: '#808080',
|
135
|
+
green: '#008000',
|
136
|
+
greenyellow: '#adff2f',
|
137
|
+
honeydew: '#f0fff0',
|
138
|
+
hotpink: '#ff69b4',
|
139
|
+
indianred: '#cd5c5c',
|
140
|
+
indigo: '#4b0082',
|
141
|
+
ivory: '#fffff0',
|
142
|
+
khaki: '#f0e68c',
|
143
|
+
lavender: '#e6e6fa',
|
144
|
+
lavenderblush: '#fff0f5',
|
145
|
+
lawngreen: '#7cfc00',
|
146
|
+
lemonchiffon: '#fffacd',
|
147
|
+
lightblue: '#add8e6',
|
148
|
+
lightcoral: '#f08080',
|
149
|
+
lightcyan: '#e0ffff',
|
150
|
+
lightgoldenrodyellow: '#fafad2',
|
151
|
+
lightgray: '#d3d3d3',
|
152
|
+
lightgrey: '#d3d3d3',
|
153
|
+
lightgreen: '#90ee90',
|
154
|
+
lightpink: '#ffb6c1',
|
155
|
+
lightsalmon: '#ffa07a',
|
156
|
+
lightseagreen: '#20b2aa',
|
157
|
+
lightskyblue: '#87cefa',
|
158
|
+
lightslategray: '#778899',
|
159
|
+
lightslategrey: '#778899',
|
160
|
+
lightsteelblue: '#b0c4de',
|
161
|
+
lightyellow: '#ffffe0',
|
162
|
+
lime: '#00ff00',
|
163
|
+
limegreen: '#32cd32',
|
164
|
+
linen: '#faf0e6',
|
165
|
+
magenta: '#ff00ff',
|
166
|
+
maroon: '#800000',
|
167
|
+
mediumaquamarine: '#66cdaa',
|
168
|
+
mediumblue: '#0000cd',
|
169
|
+
mediumorchid: '#ba55d3',
|
170
|
+
mediumpurple: '#9370db',
|
171
|
+
mediumseagreen: '#3cb371',
|
172
|
+
mediumslateblue: '#7b68ee',
|
173
|
+
mediumspringgreen: '#00fa9a',
|
174
|
+
mediumturquoise: '#48d1cc',
|
175
|
+
mediumvioletred: '#c71585',
|
176
|
+
midnightblue: '#191970',
|
177
|
+
mintcream: '#f5fffa',
|
178
|
+
mistyrose: '#ffe4e1',
|
179
|
+
moccasin: '#ffe4b5',
|
180
|
+
navajowhite: '#ffdead',
|
181
|
+
navy: '#000080',
|
182
|
+
oldlace: '#fdf5e6',
|
183
|
+
olive: '#808000',
|
184
|
+
olivedrab: '#6b8e23',
|
185
|
+
orange: '#ffa500',
|
186
|
+
orangered: '#ff4500',
|
187
|
+
orchid: '#da70d6',
|
188
|
+
palegoldenrod: '#eee8aa',
|
189
|
+
palegreen: '#98fb98',
|
190
|
+
paleturquoise: '#afeeee',
|
191
|
+
palevioletred: '#db7093',
|
192
|
+
papayawhip: '#ffefd5',
|
193
|
+
peachpuff: '#ffdab9',
|
194
|
+
peru: '#cd853f',
|
195
|
+
pink: '#ffc0cb',
|
196
|
+
plum: '#dda0dd',
|
197
|
+
powderblue: '#b0e0e6',
|
198
|
+
purple: '#800080',
|
199
|
+
rebeccapurple: '#663399',
|
200
|
+
red: '#ff0000',
|
201
|
+
rosybrown: '#bc8f8f',
|
202
|
+
royalblue: '#4169e1',
|
203
|
+
saddlebrown: '#8b4513',
|
204
|
+
salmon: '#fa8072',
|
205
|
+
sandybrown: '#f4a460',
|
206
|
+
seagreen: '#2e8b57',
|
207
|
+
seashell: '#fff5ee',
|
208
|
+
sienna: '#a0522d',
|
209
|
+
silver: '#c0c0c0',
|
210
|
+
skyblue: '#87ceeb',
|
211
|
+
slateblue: '#6a5acd',
|
212
|
+
slategray: '#708090',
|
213
|
+
slategrey: '#708090',
|
214
|
+
snow: '#fffafa',
|
215
|
+
springgreen: '#00ff7f',
|
216
|
+
steelblue: '#4682b4',
|
217
|
+
tan: '#d2b48c',
|
218
|
+
teal: '#008080',
|
219
|
+
thistle: '#d8bfd8',
|
220
|
+
tomato: '#ff6347',
|
221
|
+
turquoise: '#40e0d0',
|
222
|
+
violet: '#ee82ee',
|
223
|
+
wheat: '#f5deb3',
|
224
|
+
white: '#ffffff',
|
225
|
+
whitesmoke: '#f5f5f5',
|
226
|
+
yellow: '#ffff00',
|
227
|
+
yellowgreen: '#9acd32',
|
228
|
+
};
|
229
|
+
/**
|
230
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
231
|
+
*/
|
232
|
+
|
233
|
+
/**
|
234
|
+
* Validates that a channel value is a valid number within the range of 0 to 255.
|
235
|
+
* Throws an error if the value is not valid.
|
236
|
+
*
|
237
|
+
* @param channelName - The name of the channel being validated.
|
238
|
+
* @param value - The value of the channel to validate.
|
239
|
+
* @throws Will throw an error if the value is not a valid channel number.
|
240
|
+
*
|
241
|
+
* @private util of `@promptbook/color`
|
242
|
+
*/
|
243
|
+
function checkChannelValue(channelName, value) {
|
244
|
+
if (typeof value !== 'number') {
|
245
|
+
throw new Error(`${channelName} channel value is not number but ${typeof value}`);
|
246
|
+
}
|
247
|
+
if (isNaN(value)) {
|
248
|
+
throw new Error(`${channelName} channel value is NaN`);
|
249
|
+
}
|
250
|
+
if (Math.round(value) !== value) {
|
251
|
+
throw new Error(`${channelName} channel is not whole number, it is ${value}`);
|
252
|
+
}
|
253
|
+
if (value < 0) {
|
254
|
+
throw new Error(`${channelName} channel is lower than 0, it is ${value}`);
|
255
|
+
}
|
256
|
+
if (value > 255) {
|
257
|
+
throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
/**
|
261
|
+
* TODO: [🧠][🚓] Is/which combination it better to use asserts/check, validate or is utility function?
|
262
|
+
*/
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Color object represents an RGB color with alpha channel
|
266
|
+
*
|
267
|
+
* Note: There is no fromObject/toObject because the most logical way to serialize color is as a hex string (#009edd)
|
268
|
+
*
|
269
|
+
* @public exported from `@promptbook/color`
|
270
|
+
*/
|
271
|
+
class Color {
|
272
|
+
/**
|
273
|
+
* Creates a new Color instance from miscellaneous formats
|
274
|
+
* - It can receive Color instance and just return the same instance
|
275
|
+
* - It can receive color in string format for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`
|
276
|
+
*
|
277
|
+
* Note: This is not including fromImage because detecting color from an image is heavy task which requires async stuff and we cannot safely determine with overloading if return value will be a promise
|
278
|
+
*
|
279
|
+
* @param color
|
280
|
+
* @returns Color object
|
281
|
+
*/
|
282
|
+
static from(color) {
|
283
|
+
if (color instanceof Color) {
|
284
|
+
return take(color);
|
285
|
+
}
|
286
|
+
else if (Color.isColor(color)) {
|
287
|
+
return take(color);
|
288
|
+
}
|
289
|
+
else if (typeof color === 'string') {
|
290
|
+
return Color.fromString(color);
|
291
|
+
}
|
292
|
+
else {
|
293
|
+
console.error({ color });
|
294
|
+
throw new Error(`Can not create color from given object`);
|
295
|
+
}
|
296
|
+
}
|
297
|
+
/**
|
298
|
+
* Creates a new Color instance from miscellaneous string formats
|
299
|
+
*
|
300
|
+
* @param color as a string for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`, `red`, `darkgrey`,...
|
301
|
+
* @returns Color object
|
302
|
+
*/
|
303
|
+
static fromString(color) {
|
304
|
+
if (CSS_COLORS[color]) {
|
305
|
+
return Color.fromString(CSS_COLORS[color]);
|
306
|
+
// -----
|
307
|
+
}
|
308
|
+
else if (Color.isHexColorString(color)) {
|
309
|
+
return Color.fromHex(color);
|
310
|
+
// -----
|
311
|
+
}
|
312
|
+
else if (/^hsl\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*(\d+(?:\.\d+)?%)\)$/.test(color)) {
|
313
|
+
return Color.fromHsl(color);
|
314
|
+
// -----
|
315
|
+
}
|
316
|
+
else if (/^rgb\((\s*[0-9-.%]+\s*,?){3}\)$/.test(color)) {
|
317
|
+
// TODO: [0] Should be fromRgbString and fromRgbaString one or two functions
|
318
|
+
return Color.fromRgbString(color);
|
319
|
+
// -----
|
320
|
+
}
|
321
|
+
else if (/^rgba\((\s*[0-9-.%]+\s*,?){4}\)$/.test(color)) {
|
322
|
+
return Color.fromRgbaString(color);
|
323
|
+
// -----
|
324
|
+
}
|
325
|
+
else {
|
326
|
+
throw new Error(`Can not create a new Color instance from string "${color}".`);
|
327
|
+
}
|
328
|
+
}
|
329
|
+
/**
|
330
|
+
* Gets common color
|
331
|
+
*
|
332
|
+
* @param key as a css string like `midnightblue`
|
333
|
+
* @returns Color object
|
334
|
+
*/
|
335
|
+
static get(key) {
|
336
|
+
if (!CSS_COLORS[key]) {
|
337
|
+
throw new Error(`"${key}" is not a common css color.`);
|
338
|
+
}
|
339
|
+
return Color.fromString(CSS_COLORS[key]);
|
340
|
+
}
|
341
|
+
/**
|
342
|
+
* Creates a new Color instance from average color of given image
|
343
|
+
*
|
344
|
+
* @param image as a source for example `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYJh39z8ABJgCe/ZvAS4AAAAASUVORK5CYII=`
|
345
|
+
* @returns Color object
|
346
|
+
*/
|
347
|
+
static async fromImage(image) {
|
348
|
+
return Color.fromHex(`#009edd`);
|
349
|
+
}
|
350
|
+
/**
|
351
|
+
* Creates a new Color instance from color in hex format
|
352
|
+
*
|
353
|
+
* @param color in hex for example `#009edd`, `009edd`, `#555`,...
|
354
|
+
* @returns Color object
|
355
|
+
*/
|
356
|
+
static fromHex(hex) {
|
357
|
+
const hexOriginal = hex;
|
358
|
+
if (hex.startsWith('#')) {
|
359
|
+
hex = hex.substring(1);
|
360
|
+
}
|
361
|
+
if (hex.length === 3) {
|
362
|
+
return Color.fromHex3(hex);
|
363
|
+
}
|
364
|
+
if (hex.length === 6) {
|
365
|
+
return Color.fromHex6(hex);
|
366
|
+
}
|
367
|
+
if (hex.length === 8) {
|
368
|
+
return Color.fromHex8(hex);
|
369
|
+
}
|
370
|
+
throw new Error(`Can not parse color from hex string "${hexOriginal}"`);
|
371
|
+
}
|
372
|
+
/**
|
373
|
+
* Creates a new Color instance from color in hex format with 3 color digits (without alpha channel)
|
374
|
+
*
|
375
|
+
* @param color in hex for example `09d`
|
376
|
+
* @returns Color object
|
377
|
+
*/
|
378
|
+
static fromHex3(hex) {
|
379
|
+
const r = parseInt(hex.substr(0, 1), 16) * 16;
|
380
|
+
const g = parseInt(hex.substr(1, 1), 16) * 16;
|
381
|
+
const b = parseInt(hex.substr(2, 1), 16) * 16;
|
382
|
+
return take(new Color(r, g, b));
|
383
|
+
}
|
384
|
+
/**
|
385
|
+
* Creates a new Color instance from color in hex format with 6 color digits (without alpha channel)
|
386
|
+
*
|
387
|
+
* @param color in hex for example `009edd`
|
388
|
+
* @returns Color object
|
389
|
+
*/
|
390
|
+
static fromHex6(hex) {
|
391
|
+
const r = parseInt(hex.substr(0, 2), 16);
|
392
|
+
const g = parseInt(hex.substr(2, 2), 16);
|
393
|
+
const b = parseInt(hex.substr(4, 2), 16);
|
394
|
+
return take(new Color(r, g, b));
|
395
|
+
}
|
396
|
+
/**
|
397
|
+
* Creates a new Color instance from color in hex format with 8 color digits (with alpha channel)
|
398
|
+
*
|
399
|
+
* @param color in hex for example `009edd`
|
400
|
+
* @returns Color object
|
401
|
+
*/
|
402
|
+
static fromHex8(hex) {
|
403
|
+
const r = parseInt(hex.substr(0, 2), 16);
|
404
|
+
const g = parseInt(hex.substr(2, 2), 16);
|
405
|
+
const b = parseInt(hex.substr(4, 2), 16);
|
406
|
+
const a = parseInt(hex.substr(6, 2), 16);
|
407
|
+
return take(new Color(r, g, b, a));
|
408
|
+
}
|
409
|
+
/**
|
410
|
+
* Creates a new Color instance from color in hsl format
|
411
|
+
*
|
412
|
+
* @param color as a hsl for example `hsl(197.1,100%,43.3%)`
|
413
|
+
* @returns Color object
|
414
|
+
*/
|
415
|
+
static fromHsl(hsl) {
|
416
|
+
const match = hsl.match(/^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/);
|
417
|
+
if (!match) {
|
418
|
+
throw new Error(`Invalid hsl string format: "${hsl}"`);
|
419
|
+
}
|
420
|
+
const h = parseFloat(match[1]);
|
421
|
+
const s = parseFloat(match[2]) / 100;
|
422
|
+
const l = parseFloat(match[3]) / 100;
|
423
|
+
// HSL to RGB conversion
|
424
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
425
|
+
const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
|
426
|
+
const m = l - c / 2;
|
427
|
+
let r1 = 0, g1 = 0, b1 = 0;
|
428
|
+
if (h >= 0 && h < 60) {
|
429
|
+
r1 = c;
|
430
|
+
g1 = x;
|
431
|
+
b1 = 0;
|
432
|
+
}
|
433
|
+
else if (h >= 60 && h < 120) {
|
434
|
+
r1 = x;
|
435
|
+
g1 = c;
|
436
|
+
b1 = 0;
|
437
|
+
}
|
438
|
+
else if (h >= 120 && h < 180) {
|
439
|
+
r1 = 0;
|
440
|
+
g1 = c;
|
441
|
+
b1 = x;
|
442
|
+
}
|
443
|
+
else if (h >= 180 && h < 240) {
|
444
|
+
r1 = 0;
|
445
|
+
g1 = x;
|
446
|
+
b1 = c;
|
447
|
+
}
|
448
|
+
else if (h >= 240 && h < 300) {
|
449
|
+
r1 = x;
|
450
|
+
g1 = 0;
|
451
|
+
b1 = c;
|
452
|
+
}
|
453
|
+
else if (h >= 300 && h < 360) {
|
454
|
+
r1 = c;
|
455
|
+
g1 = 0;
|
456
|
+
b1 = x;
|
457
|
+
}
|
458
|
+
const r = Math.round((r1 + m) * 255);
|
459
|
+
const g = Math.round((g1 + m) * 255);
|
460
|
+
const b = Math.round((b1 + m) * 255);
|
461
|
+
return take(new Color(r, g, b));
|
462
|
+
}
|
463
|
+
/**
|
464
|
+
* Creates a new Color instance from color in rgb format
|
465
|
+
*
|
466
|
+
* @param color as a rgb for example `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`
|
467
|
+
* @returns Color object
|
468
|
+
*/
|
469
|
+
static fromRgbString(rgb) {
|
470
|
+
const match = rgb.match(/^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/);
|
471
|
+
if (!match) {
|
472
|
+
throw new Error(`Invalid rgb string format: "${rgb}"`);
|
473
|
+
}
|
474
|
+
const parseChannel = (value) => {
|
475
|
+
if (value.endsWith('%')) {
|
476
|
+
// Percentage value
|
477
|
+
const percent = parseFloat(value);
|
478
|
+
return Math.round((percent / 100) * 255);
|
479
|
+
}
|
480
|
+
else {
|
481
|
+
// Numeric value
|
482
|
+
return Math.round(parseFloat(value));
|
483
|
+
}
|
484
|
+
};
|
485
|
+
const r = parseChannel(match[1]);
|
486
|
+
const g = parseChannel(match[2]);
|
487
|
+
const b = parseChannel(match[3]);
|
488
|
+
return take(new Color(r, g, b));
|
489
|
+
}
|
490
|
+
/**
|
491
|
+
* Creates a new Color instance from color in rbga format
|
492
|
+
*
|
493
|
+
* @param color as a rgba for example `rgba(0,158,221,0.5)`, `rgb(0%,62%,86.7%,50%)`
|
494
|
+
* @returns Color object
|
495
|
+
*/
|
496
|
+
static fromRgbaString(rgba) {
|
497
|
+
const match = rgba.match(/^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/);
|
498
|
+
if (!match) {
|
499
|
+
throw new Error(`Invalid rgba string format: "${rgba}"`);
|
500
|
+
}
|
501
|
+
const parseChannel = (value) => {
|
502
|
+
if (value.endsWith('%')) {
|
503
|
+
const percent = parseFloat(value);
|
504
|
+
return Math.round((percent / 100) * 255);
|
505
|
+
}
|
506
|
+
else {
|
507
|
+
return Math.round(parseFloat(value));
|
508
|
+
}
|
509
|
+
};
|
510
|
+
const parseAlpha = (value) => {
|
511
|
+
if (value.endsWith('%')) {
|
512
|
+
const percent = parseFloat(value);
|
513
|
+
return Math.round((percent / 100) * 255);
|
514
|
+
}
|
515
|
+
else {
|
516
|
+
const alphaFloat = parseFloat(value);
|
517
|
+
// If alpha is between 0 and 1, treat as float
|
518
|
+
if (alphaFloat <= 1) {
|
519
|
+
return Math.round(alphaFloat * 255);
|
520
|
+
}
|
521
|
+
// Otherwise, treat as 0-255
|
522
|
+
return Math.round(alphaFloat);
|
523
|
+
}
|
524
|
+
};
|
525
|
+
const r = parseChannel(match[1]);
|
526
|
+
const g = parseChannel(match[2]);
|
527
|
+
const b = parseChannel(match[3]);
|
528
|
+
const a = parseAlpha(match[4]);
|
529
|
+
return take(new Color(r, g, b, a));
|
530
|
+
}
|
531
|
+
/**
|
532
|
+
* Creates a new Color for color channels values
|
533
|
+
*
|
534
|
+
* @param red number from 0 to 255
|
535
|
+
* @param green number from 0 to 255
|
536
|
+
* @param blue number from 0 to 255
|
537
|
+
* @param alpha number from 0 (transparent) to 255 (opaque = default)
|
538
|
+
* @returns Color object
|
539
|
+
*/
|
540
|
+
static fromValues(red, green, blue, alpha = 255) {
|
541
|
+
return take(new Color(red, green, blue, alpha));
|
542
|
+
}
|
543
|
+
/**
|
544
|
+
* Checks if the given value is a valid Color object.
|
545
|
+
*
|
546
|
+
* @param {unknown} value - The value to check.
|
547
|
+
* @return {value is WithTake<Color>} Returns true if the value is a valid Color object, false otherwise.
|
548
|
+
*/
|
549
|
+
static isColor(value) {
|
550
|
+
if (typeof value !== 'object') {
|
551
|
+
return false;
|
552
|
+
}
|
553
|
+
if (value === null) {
|
554
|
+
return false;
|
555
|
+
}
|
556
|
+
if (typeof value.red !== 'number' ||
|
557
|
+
typeof value.green !== 'number' ||
|
558
|
+
typeof value.blue !== 'number' ||
|
559
|
+
typeof value.alpha !== 'number') {
|
560
|
+
return false;
|
561
|
+
}
|
562
|
+
if (typeof value.then !== 'function') {
|
563
|
+
return false;
|
564
|
+
}
|
565
|
+
return true;
|
566
|
+
}
|
567
|
+
/**
|
568
|
+
* Checks if the given value is a valid hex color string
|
569
|
+
*
|
570
|
+
* @param value - value to check
|
571
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
572
|
+
*/
|
573
|
+
static isHexColorString(value) {
|
574
|
+
return typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(value);
|
575
|
+
}
|
576
|
+
/**
|
577
|
+
* Creates new Color object
|
578
|
+
*
|
579
|
+
* Note: Consider using one of static methods like `from` or `fromString`
|
580
|
+
*
|
581
|
+
* @param red number from 0 to 255
|
582
|
+
* @param green number from 0 to 255
|
583
|
+
* @param blue number from 0 to 255
|
584
|
+
* @param alpha number from 0 (transparent) to 255 (opaque)
|
585
|
+
*/
|
586
|
+
constructor(red, green, blue, alpha = 255) {
|
587
|
+
this.red = red;
|
588
|
+
this.green = green;
|
589
|
+
this.blue = blue;
|
590
|
+
this.alpha = alpha;
|
591
|
+
checkChannelValue('Red', red);
|
592
|
+
checkChannelValue('Green', green);
|
593
|
+
checkChannelValue('Blue', blue);
|
594
|
+
checkChannelValue('Alpha', alpha);
|
595
|
+
}
|
596
|
+
/**
|
597
|
+
* Shortcut for `red` property
|
598
|
+
* Number from 0 to 255
|
599
|
+
* @alias red
|
600
|
+
*/
|
601
|
+
get r() {
|
602
|
+
return this.red;
|
603
|
+
}
|
604
|
+
/**
|
605
|
+
* Shortcut for `green` property
|
606
|
+
* Number from 0 to 255
|
607
|
+
* @alias green
|
608
|
+
*/
|
609
|
+
get g() {
|
610
|
+
return this.green;
|
611
|
+
}
|
612
|
+
/**
|
613
|
+
* Shortcut for `blue` property
|
614
|
+
* Number from 0 to 255
|
615
|
+
* @alias blue
|
616
|
+
*/
|
617
|
+
get b() {
|
618
|
+
return this.blue;
|
619
|
+
}
|
620
|
+
/**
|
621
|
+
* Shortcut for `alpha` property
|
622
|
+
* Number from 0 (transparent) to 255 (opaque)
|
623
|
+
* @alias alpha
|
624
|
+
*/
|
625
|
+
get a() {
|
626
|
+
return this.alpha;
|
627
|
+
}
|
628
|
+
/**
|
629
|
+
* Shortcut for `alpha` property
|
630
|
+
* Number from 0 (transparent) to 255 (opaque)
|
631
|
+
* @alias alpha
|
632
|
+
*/
|
633
|
+
get opacity() {
|
634
|
+
return this.alpha;
|
635
|
+
}
|
636
|
+
/**
|
637
|
+
* Shortcut for 1-`alpha` property
|
638
|
+
*/
|
639
|
+
get transparency() {
|
640
|
+
return 255 - this.alpha;
|
641
|
+
}
|
642
|
+
clone() {
|
643
|
+
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
644
|
+
}
|
645
|
+
toString() {
|
646
|
+
return this.toHex();
|
647
|
+
}
|
648
|
+
toHex() {
|
649
|
+
if (this.alpha === 255) {
|
650
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
651
|
+
.toString(16)
|
652
|
+
.padStart(2, '0')}`;
|
653
|
+
}
|
654
|
+
else {
|
655
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
656
|
+
.toString(16)
|
657
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
658
|
+
}
|
659
|
+
}
|
660
|
+
toRgb() {
|
661
|
+
if (this.alpha === 255) {
|
662
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
663
|
+
}
|
664
|
+
else {
|
665
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
666
|
+
}
|
667
|
+
}
|
668
|
+
toHsl() {
|
669
|
+
throw new Error(`Getting HSL is not implemented`);
|
670
|
+
}
|
671
|
+
}
|
672
|
+
/**
|
673
|
+
* TODO: [🥻] Split Color class and color type
|
674
|
+
* TODO: For each method a corresponding static method should be created
|
675
|
+
* Like clone can be done by color.clone() OR Color.clone(color)
|
676
|
+
* TODO: Probably as an independent LIB OR add to LIB xyzt (ask @roseckyj)
|
677
|
+
* TODO: !! Transfer back to Collboard (whole directory)
|
678
|
+
* TODO: Maybe [🏌️♂️] change ACRY toString => (toHex) toRgb when there will be toRgb and toRgba united
|
679
|
+
* TODO: Convert getters to methods - getters only for values
|
680
|
+
* TODO: Write tests
|
681
|
+
* TODO: Getters for alpha, opacity, transparency, r, b, g, h, s, l, a,...
|
682
|
+
* TODO: [0] Should be fromRgbString and fromRgbaString one or two functions + one or two regex
|
683
|
+
* TODO: Use rgb, rgba, hsl for testing and parsing with the same regex
|
684
|
+
* TODO: Regex for rgb, rgba, hsl does not support all options like deg, rad, turn,...
|
685
|
+
* TODO: Convolution matrix
|
686
|
+
* TODO: Maybe connect with textures
|
687
|
+
*/
|
688
|
+
|
689
|
+
/**
|
690
|
+
* Converts HSL values to RGB values
|
691
|
+
*
|
692
|
+
* @param hue [0-1]
|
693
|
+
* @param saturation [0-1]
|
694
|
+
* @param lightness [0-1]
|
695
|
+
* @returns [red, green, blue] [0-255]
|
696
|
+
*
|
697
|
+
* @private util of `@promptbook/color`
|
698
|
+
*/
|
699
|
+
function hslToRgb(hue, saturation, lightness) {
|
700
|
+
let red;
|
701
|
+
let green;
|
702
|
+
let blue;
|
703
|
+
if (saturation === 0) {
|
704
|
+
// achromatic
|
705
|
+
red = lightness;
|
706
|
+
green = lightness;
|
707
|
+
blue = lightness;
|
708
|
+
}
|
709
|
+
else {
|
710
|
+
// TODO: Extract to separate function
|
711
|
+
const hue2rgb = (p, q, t) => {
|
712
|
+
if (t < 0)
|
713
|
+
t += 1;
|
714
|
+
if (t > 1)
|
715
|
+
t -= 1;
|
716
|
+
if (t < 1 / 6)
|
717
|
+
return p + (q - p) * 6 * t;
|
718
|
+
if (t < 1 / 2)
|
719
|
+
return q;
|
720
|
+
if (t < 2 / 3)
|
721
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
722
|
+
return p;
|
723
|
+
};
|
724
|
+
const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
|
725
|
+
const p = 2 * lightness - q;
|
726
|
+
red = hue2rgb(p, q, hue + 1 / 3);
|
727
|
+
green = hue2rgb(p, q, hue);
|
728
|
+
blue = hue2rgb(p, q, hue - 1 / 3);
|
729
|
+
}
|
730
|
+
return [Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255)];
|
731
|
+
}
|
732
|
+
/**
|
733
|
+
* TODO: Properly name all used internal variables
|
734
|
+
*/
|
735
|
+
|
736
|
+
/**
|
737
|
+
* Converts RGB values to HSL values
|
738
|
+
*
|
739
|
+
* @param red [0-255]
|
740
|
+
* @param green [0-255]
|
741
|
+
* @param blue [0-255]
|
742
|
+
* @returns [hue, saturation, lightness] [0-1]
|
743
|
+
*
|
744
|
+
* @private util of `@promptbook/color`
|
745
|
+
*/
|
746
|
+
function rgbToHsl(red, green, blue) {
|
747
|
+
red /= 255;
|
748
|
+
green /= 255;
|
749
|
+
blue /= 255;
|
750
|
+
const max = Math.max(red, green, blue);
|
751
|
+
const min = Math.min(red, green, blue);
|
752
|
+
let hue;
|
753
|
+
let saturation;
|
754
|
+
const lightness = (max + min) / 2;
|
755
|
+
if (max === min) {
|
756
|
+
// achromatic
|
757
|
+
hue = 0;
|
758
|
+
saturation = 0;
|
759
|
+
}
|
760
|
+
else {
|
761
|
+
const d = max - min;
|
762
|
+
saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min);
|
763
|
+
switch (max) {
|
764
|
+
case red:
|
765
|
+
hue = (green - blue) / d + (green < blue ? 6 : 0);
|
766
|
+
break;
|
767
|
+
case green:
|
768
|
+
hue = (blue - red) / d + 2;
|
769
|
+
break;
|
770
|
+
case blue:
|
771
|
+
hue = (red - green) / d + 4;
|
772
|
+
break;
|
773
|
+
default:
|
774
|
+
hue = 0;
|
775
|
+
}
|
776
|
+
hue /= 6;
|
777
|
+
}
|
778
|
+
return [hue, saturation, lightness];
|
779
|
+
}
|
780
|
+
/**
|
781
|
+
* TODO: Properly name all used internal variables
|
782
|
+
*/
|
783
|
+
|
784
|
+
/**
|
785
|
+
* Makes color transformer which lighten the given color
|
786
|
+
*
|
787
|
+
* @param amount from 0 to 1
|
788
|
+
*
|
789
|
+
* @public exported from `@promptbook/color`
|
790
|
+
*/
|
791
|
+
function lighten(amount) {
|
792
|
+
return ({ red, green, blue, alpha }) => {
|
793
|
+
const [h, s, lInitial] = rgbToHsl(red, green, blue);
|
794
|
+
let l = lInitial + amount;
|
795
|
+
l = Math.max(0, Math.min(l, 1)); // Replace lodash clamp with Math.max and Math.min
|
796
|
+
const [r, g, b] = hslToRgb(h, s, l);
|
797
|
+
return Color.fromValues(r, g, b, alpha);
|
798
|
+
};
|
799
|
+
}
|
800
|
+
/**
|
801
|
+
* TODO: Maybe implement by mix+hsl
|
802
|
+
*/
|
803
|
+
|
804
|
+
/**
|
805
|
+
* Calculates distance between two colors
|
806
|
+
*
|
807
|
+
* @param color1 first color
|
808
|
+
* @param color2 second color
|
809
|
+
*
|
810
|
+
* Note: This function is inefficient. Use colorDistanceSquared instead if possible.
|
811
|
+
*
|
812
|
+
* @public exported from `@promptbook/color`
|
813
|
+
*/
|
814
|
+
/**
|
815
|
+
* Calculates distance between two colors without square root
|
816
|
+
*
|
817
|
+
* @param color1 first color
|
818
|
+
* @param color2 second color
|
819
|
+
*
|
820
|
+
* @public exported from `@promptbook/color`
|
821
|
+
*/
|
822
|
+
function colorDistanceSquared(color1, color2) {
|
823
|
+
const rmean = (color1.red + color2.red) / 2;
|
824
|
+
const r = color1.red - color2.red;
|
825
|
+
const g = color1.green - color2.green;
|
826
|
+
const b = color1.blue - color2.blue;
|
827
|
+
const weightR = 2 + rmean / 256;
|
828
|
+
const weightG = 4.0;
|
829
|
+
const weightB = 2 + (255 - rmean) / 256;
|
830
|
+
const distance = weightR * r * r + weightG * g * g + weightB * b * b;
|
831
|
+
return distance;
|
832
|
+
}
|
833
|
+
|
834
|
+
/**
|
835
|
+
* Makes color transformer which finds the nearest color from the given list
|
836
|
+
*
|
837
|
+
* @param colors array of colors to choose from
|
838
|
+
*
|
839
|
+
* @public exported from `@promptbook/color`
|
840
|
+
*/
|
841
|
+
function nearest(...colors) {
|
842
|
+
return (color) => {
|
843
|
+
const distances = colors.map((c) => colorDistanceSquared(c, color));
|
844
|
+
const minDistance = Math.min(...distances);
|
845
|
+
const minIndex = distances.indexOf(minDistance);
|
846
|
+
const nearestColor = colors[minIndex];
|
847
|
+
return nearestColor;
|
848
|
+
};
|
849
|
+
}
|
850
|
+
|
851
|
+
/**
|
852
|
+
* Color transformer which returns the negative color
|
853
|
+
*
|
854
|
+
* @public exported from `@promptbook/color`
|
855
|
+
*/
|
856
|
+
function negative(color) {
|
857
|
+
const r = 255 - color.red;
|
858
|
+
const g = 255 - color.green;
|
859
|
+
const b = 255 - color.blue;
|
860
|
+
return Color.fromValues(r, g, b, color.alpha);
|
861
|
+
}
|
862
|
+
|
863
|
+
/**
|
864
|
+
* Makes color transformer which finds the furthest color from the given list
|
865
|
+
*
|
866
|
+
* @param colors array of colors to choose from
|
867
|
+
*
|
868
|
+
* @public exported from `@promptbook/color`
|
869
|
+
*/
|
870
|
+
function furthest(...colors) {
|
871
|
+
return (color) => {
|
872
|
+
const furthestColor = negative(nearest(...colors.map(negative))(color));
|
873
|
+
return furthestColor;
|
874
|
+
};
|
875
|
+
}
|
876
|
+
/**
|
877
|
+
* Makes color transformer which finds the best text color (black or white) for the given background color
|
878
|
+
*
|
879
|
+
* @public exported from `@promptbook/color`
|
880
|
+
*/
|
881
|
+
furthest(Color.get('white'), Color.from('black'));
|
882
|
+
|
883
|
+
/**
|
884
|
+
* Makes color transformer which returns a grayscale version of the color
|
885
|
+
*
|
886
|
+
* @param amount from 0 to 1
|
887
|
+
*
|
888
|
+
* @public exported from `@promptbook/color`
|
889
|
+
*/
|
890
|
+
function grayscale(amount) {
|
891
|
+
return ({ red, green, blue, alpha }) => {
|
892
|
+
const average = (red + green + blue) / 3;
|
893
|
+
red = Math.round(average * amount + red * (1 - amount));
|
894
|
+
green = Math.round(average * amount + green * (1 - amount));
|
895
|
+
blue = Math.round(average * amount + blue * (1 - amount));
|
896
|
+
return Color.fromValues(red, green, blue, alpha);
|
897
|
+
};
|
898
|
+
}
|
899
|
+
|
900
|
+
/**
|
901
|
+
* Makes color transformer which saturate the given color
|
902
|
+
*
|
903
|
+
* @param amount from -1 to 1
|
904
|
+
*
|
905
|
+
* @public exported from `@promptbook/color`
|
906
|
+
*/
|
907
|
+
function saturate(amount) {
|
908
|
+
return ({ red, green, blue, alpha }) => {
|
909
|
+
const [h, sInitial, l] = rgbToHsl(red, green, blue);
|
910
|
+
let s = sInitial + amount;
|
911
|
+
s = Math.max(0, Math.min(s, 1));
|
912
|
+
const [r, g, b] = hslToRgb(h, s, l);
|
913
|
+
return Color.fromValues(r, g, b, alpha);
|
914
|
+
};
|
915
|
+
}
|
916
|
+
/**
|
917
|
+
* TODO: Maybe implement by mix+hsl
|
918
|
+
*/
|
919
|
+
|
31
920
|
/**
|
32
921
|
* Name for the Promptbook
|
33
922
|
*
|
@@ -48,6 +937,32 @@
|
|
48
937
|
* @public exported from `@promptbook/core`
|
49
938
|
*/
|
50
939
|
const ADMIN_GITHUB_NAME = 'hejny';
|
940
|
+
// <- TODO: [🐊] Pick the best claim
|
941
|
+
/**
|
942
|
+
* Color of the Promptbook
|
943
|
+
*
|
944
|
+
* TODO: [🗽] Unite branding and make single place for it
|
945
|
+
*
|
946
|
+
* @public exported from `@promptbook/core`
|
947
|
+
*/
|
948
|
+
const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
|
949
|
+
// <- TODO: !!! How much is this adding to package size of @promptbook/core
|
950
|
+
/**
|
951
|
+
* Dark color of the Promptbook
|
952
|
+
*
|
953
|
+
* TODO: [🗽] Unite branding and make single place for it
|
954
|
+
*
|
955
|
+
* @public exported from `@promptbook/core`
|
956
|
+
*/
|
957
|
+
PROMPTBOOK_COLOR.then(lighten(0.1)).then(saturate(0.9)).then(grayscale(0.9));
|
958
|
+
/**
|
959
|
+
* Color of the user (in chat)
|
960
|
+
*
|
961
|
+
* TODO: [🗽] Unite branding and make single place for it
|
962
|
+
*
|
963
|
+
* @public exported from `@promptbook/core`
|
964
|
+
*/
|
965
|
+
Color.fromHex('#1D4ED8');
|
51
966
|
// <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
|
52
967
|
/**
|
53
968
|
* The maximum number of iterations for a loops
|
@@ -2598,6 +3513,68 @@
|
|
2598
3513
|
* TODO: Type the return type correctly
|
2599
3514
|
*/
|
2600
3515
|
|
3516
|
+
/**
|
3517
|
+
* Function `serializeToPromptbookJavascript` will serialize a value to a javascript representation using `@promptbook/*` entities where possible.
|
3518
|
+
*
|
3519
|
+
* @public exported from `@promptbook/utils`
|
3520
|
+
*/
|
3521
|
+
function serializeToPromptbookJavascript(value) {
|
3522
|
+
let serializedValue;
|
3523
|
+
let imports = [];
|
3524
|
+
if (value === null || value === undefined || typeof value === 'number' || typeof value === 'boolean') {
|
3525
|
+
serializedValue = JSON.stringify(value, null, 4);
|
3526
|
+
}
|
3527
|
+
else if (Array.isArray(value)) {
|
3528
|
+
const serializedItems = value.map((item) => serializeToPromptbookJavascript(item));
|
3529
|
+
serializedValue = `[${serializedItems.map((item) => item.value).join(', ')}]`;
|
3530
|
+
imports = serializedItems.flatMap((item) => item.imports);
|
3531
|
+
}
|
3532
|
+
else if (value instanceof Date) {
|
3533
|
+
serializedValue = `new Date('${value.toISOString()}')`;
|
3534
|
+
}
|
3535
|
+
else if (value instanceof Color) {
|
3536
|
+
serializedValue = `Color.fromHex('${value.toHex()}')`;
|
3537
|
+
imports.push(`import { Color } from '@promptbook/color';`);
|
3538
|
+
}
|
3539
|
+
else if (typeof value === 'string') {
|
3540
|
+
const trimmed = spaceTrim__default["default"](value);
|
3541
|
+
if (trimmed.includes('\n')) {
|
3542
|
+
// Multiline string -> use `spaceTrim`
|
3543
|
+
serializedValue = `spaceTrim(\`\n${value.replace(/`/g, '\\`')}\n\`)`;
|
3544
|
+
imports.push(`import { spaceTrim } from '@promptbook/utils';`);
|
3545
|
+
}
|
3546
|
+
else if (Color.isHexColorString(trimmed)) {
|
3547
|
+
return serializeToPromptbookJavascript(Color.fromHex(trimmed));
|
3548
|
+
}
|
3549
|
+
else {
|
3550
|
+
// Single line string -> use normal quotes
|
3551
|
+
serializedValue = JSON.stringify(value);
|
3552
|
+
}
|
3553
|
+
}
|
3554
|
+
else if (typeof value === 'object') {
|
3555
|
+
const entries = Object.entries(value).map(([key, val]) => {
|
3556
|
+
const serializedEntry = serializeToPromptbookJavascript(val);
|
3557
|
+
imports.push(...serializedEntry.imports);
|
3558
|
+
return [key, serializedEntry.value];
|
3559
|
+
});
|
3560
|
+
const objectString = `{\n${entries
|
3561
|
+
.map(([key, val]) => ` ${JSON.stringify(key)}: ${val === null || val === void 0 ? void 0 : val.split('\n').map((line) => ` ${line}`).join('\n')}`)
|
3562
|
+
.join(',\n')}\n}`;
|
3563
|
+
serializedValue = objectString;
|
3564
|
+
}
|
3565
|
+
else {
|
3566
|
+
throw new Error(`Cannot serialize to Promptbook Javascript value of type "${typeof value}"`);
|
3567
|
+
}
|
3568
|
+
if (serializedValue === undefined) {
|
3569
|
+
throw new UnexpectedError(`Serialization resulted in undefined value`);
|
3570
|
+
}
|
3571
|
+
const uniqueImports = Array.from(new Set(imports)).filter((imp) => !!imp && imp.trim().length > 0);
|
3572
|
+
return { imports: uniqueImports, value: serializedValue };
|
3573
|
+
}
|
3574
|
+
/**
|
3575
|
+
* TODO: Dynamic indentation passable through options in a second argument
|
3576
|
+
*/
|
3577
|
+
|
2601
3578
|
/**
|
2602
3579
|
* Create difference set of two sets.
|
2603
3580
|
*
|
@@ -2916,6 +3893,7 @@
|
|
2916
3893
|
exports.renderPromptbookMermaid = renderPromptbookMermaid;
|
2917
3894
|
exports.searchKeywords = searchKeywords;
|
2918
3895
|
exports.serializeError = serializeError;
|
3896
|
+
exports.serializeToPromptbookJavascript = serializeToPromptbookJavascript;
|
2919
3897
|
exports.spaceTrim = spaceTrim;
|
2920
3898
|
exports.splitIntoSentences = splitIntoSentences;
|
2921
3899
|
exports.suffixUrl = suffixUrl;
|