@schedule1-tools/mixer 0.2.2 → 0.2.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { mixSubstances, mixFromHash } from './core/mixer';
2
- export { encodeMixState, decodeMixState } from './utils/encoding';
2
+ export { encodeMixState, decodeMixState, migrateMixHash } from './utils/encoding';
3
3
  export { effects } from './data/effects';
4
4
  export { products, productAbbreviations } from './data/products';
5
5
  export { substances } from './data/substances';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.effectRulesBySubstance = exports.substances = exports.productAbbreviations = exports.products = exports.effects = exports.decodeMixState = exports.encodeMixState = exports.mixFromHash = exports.mixSubstances = void 0;
3
+ exports.effectRulesBySubstance = exports.substances = exports.productAbbreviations = exports.products = exports.effects = exports.migrateMixHash = exports.decodeMixState = exports.encodeMixState = exports.mixFromHash = exports.mixSubstances = void 0;
4
4
  // Main exports
5
5
  var mixer_1 = require("./core/mixer");
6
6
  Object.defineProperty(exports, "mixSubstances", { enumerable: true, get: function () { return mixer_1.mixSubstances; } });
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "mixFromHash", { enumerable: true, get: function
8
8
  var encoding_1 = require("./utils/encoding");
9
9
  Object.defineProperty(exports, "encodeMixState", { enumerable: true, get: function () { return encoding_1.encodeMixState; } });
10
10
  Object.defineProperty(exports, "decodeMixState", { enumerable: true, get: function () { return encoding_1.decodeMixState; } });
11
+ Object.defineProperty(exports, "migrateMixHash", { enumerable: true, get: function () { return encoding_1.migrateMixHash; } });
11
12
  // Data exports
12
13
  var effects_1 = require("./data/effects");
13
14
  Object.defineProperty(exports, "effects", { enumerable: true, get: function () { return effects_1.effects; } });
@@ -12,3 +12,9 @@ export declare function encodeMixState(state: MixState): string;
12
12
  * @returns The decoded MixState or null if invalid
13
13
  */
14
14
  export declare function decodeMixState(hash: string): MixState | null;
15
+ /**
16
+ * Migrates an old format mix hash to the new format
17
+ * @param legacyHash - The old format hash to migrate
18
+ * @returns The mix state in the new hash format, or null if migration failed
19
+ */
20
+ export declare function migrateMixHash(legacyHash: string): Promise<string | null>;
@@ -1,7 +1,41 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.encodeMixState = encodeMixState;
4
37
  exports.decodeMixState = decodeMixState;
38
+ exports.migrateMixHash = migrateMixHash;
5
39
  const products_1 = require("../data/products");
6
40
  const substances_1 = require("../data/substances");
7
41
  /**
@@ -68,6 +102,45 @@ function decodeMixState(hash) {
68
102
  return null;
69
103
  }
70
104
  }
105
+ /**
106
+ * Migrates an old format mix hash to the new format
107
+ * @param legacyHash - The old format hash to migrate
108
+ * @returns The mix state in the new hash format, or null if migration failed
109
+ */
110
+ async function migrateMixHash(legacyHash) {
111
+ try {
112
+ const LZString = await Promise.resolve().then(() => __importStar(require('lz-string')));
113
+ const jsonStr = LZString.decompressFromBase64(legacyHash);
114
+ if (!jsonStr)
115
+ return null;
116
+ const mixArr = JSON.parse(jsonStr);
117
+ if (!Array.isArray(mixArr) || !mixArr.length)
118
+ return null;
119
+ const firstMix = mixArr[0];
120
+ const productId = firstMix.weed;
121
+ if (!products_1.products[productId])
122
+ return null;
123
+ const subsByAbbr = Object.entries(substances_1.substances).reduce((map, [id, sub]) => {
124
+ if (sub.abbreviation)
125
+ map[sub.abbreviation] = id;
126
+ return map;
127
+ }, {});
128
+ const substanceIds = [];
129
+ if (Array.isArray(firstMix.substances)) {
130
+ for (const legacySubId of firstMix.substances) {
131
+ const substanceId = substances_1.substances[legacySubId]
132
+ ? legacySubId
133
+ : subsByAbbr[legacySubId];
134
+ if (substanceId)
135
+ substanceIds.push(substanceId);
136
+ }
137
+ }
138
+ return encodeMixState({ product: productId, substances: substanceIds });
139
+ }
140
+ catch (_a) {
141
+ return null;
142
+ }
143
+ }
71
144
  /**
72
145
  * Convert a string to a URL-safe base64 string
73
146
  * @param str - The string to convert
@@ -0,0 +1,5 @@
1
+ /**
2
+ * A minimal implementation of LZString's decompressFromBase64 function
3
+ * Based on the original LZ-string library but simplified for your specific use case
4
+ */
5
+ export declare function decompressFromBase64(input: string): string | null;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decompressFromBase64 = decompressFromBase64;
4
+ /**
5
+ * A minimal implementation of LZString's decompressFromBase64 function
6
+ * Based on the original LZ-string library but simplified for your specific use case
7
+ */
8
+ function decompressFromBase64(input) {
9
+ if (!input)
10
+ return null;
11
+ // Convert from base64 to a format suitable for processing
12
+ const keyStrBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
13
+ const baseReverseDic = {};
14
+ for (let i = 0; i < keyStrBase64.length; i++) {
15
+ baseReverseDic[keyStrBase64[i]] = i;
16
+ }
17
+ // Decompress the input
18
+ return _decompress(input.length, 32, (index) => {
19
+ return baseReverseDic[input.charAt(index)];
20
+ });
21
+ }
22
+ /**
23
+ * Core decompression function
24
+ */
25
+ function _decompress(length, resetValue, getNextValue) {
26
+ const dictionary = [];
27
+ let enlargeIn = 4;
28
+ let dictSize = 4;
29
+ let numBits = 3;
30
+ let result = '';
31
+ let entry = '';
32
+ let w = '';
33
+ let c = '';
34
+ let errorCount = 0;
35
+ let bits = 0;
36
+ let maxpower = Math.pow(2, 2);
37
+ let power = 1;
38
+ let resb;
39
+ let data = { val: getNextValue(0), position: resetValue, index: 1 };
40
+ for (let i = 0; i < 3; i++) {
41
+ dictionary[i] = String(i);
42
+ }
43
+ bits = 0;
44
+ maxpower = Math.pow(2, numBits);
45
+ power = 1;
46
+ while (power != maxpower) {
47
+ resb = data.val & data.position;
48
+ data.position >>= 1;
49
+ if (data.position == 0) {
50
+ data.position = resetValue;
51
+ data.val = getNextValue(data.index++);
52
+ }
53
+ bits |= (resb > 0 ? 1 : 0) * power;
54
+ power <<= 1;
55
+ }
56
+ switch (bits) {
57
+ case 0:
58
+ bits = 0;
59
+ maxpower = Math.pow(2, 8);
60
+ power = 1;
61
+ while (power != maxpower) {
62
+ resb = data.val & data.position;
63
+ data.position >>= 1;
64
+ if (data.position == 0) {
65
+ data.position = resetValue;
66
+ data.val = getNextValue(data.index++);
67
+ }
68
+ bits |= (resb > 0 ? 1 : 0) * power;
69
+ power <<= 1;
70
+ }
71
+ c = String.fromCharCode(bits);
72
+ break;
73
+ case 1:
74
+ bits = 0;
75
+ maxpower = Math.pow(2, 16);
76
+ power = 1;
77
+ while (power != maxpower) {
78
+ resb = data.val & data.position;
79
+ data.position >>= 1;
80
+ if (data.position == 0) {
81
+ data.position = resetValue;
82
+ data.val = getNextValue(data.index++);
83
+ }
84
+ bits |= (resb > 0 ? 1 : 0) * power;
85
+ power <<= 1;
86
+ }
87
+ c = String.fromCharCode(bits);
88
+ break;
89
+ case 2:
90
+ return '';
91
+ }
92
+ dictionary[3] = c;
93
+ w = c;
94
+ result = c;
95
+ while (true) {
96
+ if (data.index > length) {
97
+ return null;
98
+ }
99
+ bits = 0;
100
+ maxpower = Math.pow(2, numBits);
101
+ power = 1;
102
+ while (power != maxpower) {
103
+ resb = data.val & data.position;
104
+ data.position >>= 1;
105
+ if (data.position == 0) {
106
+ data.position = resetValue;
107
+ data.val = getNextValue(data.index++);
108
+ }
109
+ bits |= (resb > 0 ? 1 : 0) * power;
110
+ power <<= 1;
111
+ }
112
+ switch ((c = bits)) {
113
+ case 0:
114
+ bits = 0;
115
+ maxpower = Math.pow(2, 8);
116
+ power = 1;
117
+ while (power != maxpower) {
118
+ resb = data.val & data.position;
119
+ data.position >>= 1;
120
+ if (data.position == 0) {
121
+ data.position = resetValue;
122
+ data.val = getNextValue(data.index++);
123
+ }
124
+ bits |= (resb > 0 ? 1 : 0) * power;
125
+ power <<= 1;
126
+ }
127
+ dictionary[dictSize++] = String.fromCharCode(bits);
128
+ c = dictSize - 1;
129
+ enlargeIn--;
130
+ break;
131
+ case 1:
132
+ bits = 0;
133
+ maxpower = Math.pow(2, 16);
134
+ power = 1;
135
+ while (power != maxpower) {
136
+ resb = data.val & data.position;
137
+ data.position >>= 1;
138
+ if (data.position == 0) {
139
+ data.position = resetValue;
140
+ data.val = getNextValue(data.index++);
141
+ }
142
+ bits |= (resb > 0 ? 1 : 0) * power;
143
+ power <<= 1;
144
+ }
145
+ dictionary[dictSize++] = String.fromCharCode(bits);
146
+ c = dictSize - 1;
147
+ enlargeIn--;
148
+ break;
149
+ case 2:
150
+ return result;
151
+ }
152
+ if (enlargeIn == 0) {
153
+ enlargeIn = Math.pow(2, numBits);
154
+ numBits++;
155
+ }
156
+ if (typeof c === 'number' && dictionary[c]) {
157
+ entry = dictionary[c];
158
+ }
159
+ else {
160
+ if (typeof c === 'number' && c === dictSize) {
161
+ entry = w + w.charAt(0);
162
+ }
163
+ else {
164
+ return null;
165
+ }
166
+ }
167
+ result += entry;
168
+ // Add w+entry[0] to the dictionary
169
+ dictionary[dictSize++] = w + entry.charAt(0);
170
+ enlargeIn--;
171
+ w = entry;
172
+ if (enlargeIn == 0) {
173
+ enlargeIn = Math.pow(2, numBits);
174
+ numBits++;
175
+ }
176
+ }
177
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schedule1-tools/mixer",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "A package for calculating substance mixes in Schedule 1",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,6 +12,9 @@
12
12
  ],
13
13
  "author": "Schedule1 Tools",
14
14
  "license": "MIT",
15
+ "dependencies": {
16
+ "lz-string": "^1.5.0"
17
+ },
15
18
  "devDependencies": {
16
19
  "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
17
20
  "@types/jest": "^29.5.14",