beardos-toolbox 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +48 -31
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +33 -26
- package/dist/index.mjs.map +2 -2
- package/dist/s3.d.ts +4 -2
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// index.ts
|
|
@@ -79,69 +89,76 @@ __export(s3_exports, {
|
|
|
79
89
|
listObjects: () => listObjects,
|
|
80
90
|
putObject: () => putObject
|
|
81
91
|
});
|
|
82
|
-
var
|
|
92
|
+
var _mod = null;
|
|
93
|
+
async function getModule() {
|
|
94
|
+
if (!_mod) {
|
|
95
|
+
try {
|
|
96
|
+
_mod = await import("@aws-sdk/client-s3");
|
|
97
|
+
} catch {
|
|
98
|
+
throw new Error(
|
|
99
|
+
"[beardos-toolbox] @aws-sdk/client-s3 is required to use the S3 helpers. Install it: npm i @aws-sdk/client-s3"
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return _mod;
|
|
104
|
+
}
|
|
83
105
|
var client;
|
|
84
|
-
var getClient = ({ region, accessKeyId, secretAccessKey }) => {
|
|
106
|
+
var getClient = async ({ region, accessKeyId, secretAccessKey }) => {
|
|
85
107
|
if (!client) {
|
|
86
|
-
|
|
108
|
+
const { S3Client } = await getModule();
|
|
109
|
+
client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });
|
|
87
110
|
}
|
|
88
111
|
return client;
|
|
89
112
|
};
|
|
90
113
|
var putObject = async (config, data, key, contentType) => {
|
|
91
114
|
try {
|
|
92
|
-
const
|
|
115
|
+
const { PutObjectCommand } = await getModule();
|
|
116
|
+
const cl = await getClient(config);
|
|
93
117
|
const params = {
|
|
94
118
|
Bucket: config.bucket,
|
|
95
119
|
Key: key,
|
|
96
120
|
Body: typeof data === "string" ? Buffer.from(data, "utf-8") : data
|
|
97
121
|
};
|
|
98
|
-
if (contentType)
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
return await cl.send(new import_client_s3.PutObjectCommand(params));
|
|
122
|
+
if (contentType) params.ContentType = contentType;
|
|
123
|
+
return await cl.send(new PutObjectCommand(params));
|
|
102
124
|
} catch (e) {
|
|
103
|
-
console.error("Could not upload
|
|
125
|
+
console.error("Could not upload object", { error: e });
|
|
104
126
|
throw e;
|
|
105
127
|
}
|
|
106
128
|
};
|
|
107
129
|
var getObject = async (config, key) => {
|
|
108
|
-
const params = {
|
|
109
|
-
Bucket: config.bucket,
|
|
110
|
-
Key: key
|
|
111
|
-
};
|
|
130
|
+
const params = { Bucket: config.bucket, Key: key };
|
|
112
131
|
try {
|
|
113
|
-
const
|
|
114
|
-
|
|
132
|
+
const { GetObjectCommand } = await getModule();
|
|
133
|
+
const cl = await getClient(config);
|
|
134
|
+
return await cl.send(new GetObjectCommand(params));
|
|
115
135
|
} catch (e) {
|
|
116
136
|
console.error("Could not get object from s3", { error: e, params });
|
|
117
137
|
throw e;
|
|
118
138
|
}
|
|
119
139
|
};
|
|
120
140
|
var listObjects = async (config, prefix, Marker) => {
|
|
121
|
-
const params = {
|
|
122
|
-
Bucket: config.bucket,
|
|
123
|
-
Prefix: prefix
|
|
124
|
-
};
|
|
125
|
-
if (Marker) {
|
|
126
|
-
params.StartAfter = Marker;
|
|
127
|
-
}
|
|
128
141
|
try {
|
|
129
|
-
const
|
|
130
|
-
const
|
|
142
|
+
const { ListObjectsV2Command } = await getModule();
|
|
143
|
+
const cl = await getClient(config);
|
|
144
|
+
const params = {
|
|
145
|
+
Bucket: config.bucket,
|
|
146
|
+
Prefix: prefix,
|
|
147
|
+
...Marker ? { StartAfter: Marker } : {}
|
|
148
|
+
};
|
|
149
|
+
const response = await cl.send(new ListObjectsV2Command(params));
|
|
131
150
|
return { Objects: response.Contents ?? [], Marker: response.NextContinuationToken };
|
|
132
151
|
} catch (e) {
|
|
133
|
-
console.error("Could not
|
|
152
|
+
console.error("Could not list objects", { error: e });
|
|
134
153
|
throw e;
|
|
135
154
|
}
|
|
136
155
|
};
|
|
137
156
|
var deleteObject = async (config, Key) => {
|
|
138
|
-
const params = {
|
|
139
|
-
Bucket: config.bucket,
|
|
140
|
-
Key
|
|
141
|
-
};
|
|
157
|
+
const params = { Bucket: config.bucket, Key };
|
|
142
158
|
try {
|
|
143
|
-
const
|
|
144
|
-
|
|
159
|
+
const { DeleteObjectCommand } = await getModule();
|
|
160
|
+
const cl = await getClient(config);
|
|
161
|
+
return await cl.send(new DeleteObjectCommand(params));
|
|
145
162
|
} catch (e) {
|
|
146
163
|
console.error("Could not delete object from s3", { error: e, params });
|
|
147
164
|
throw e;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../index.ts", "../s3.ts", "../jsonl.ts", "../misc-js-funcs.ts", "../tile-map.ts"],
|
|
4
|
-
"sourcesContent": ["import * as s3 from './s3'\r\nexport * from './s3'\r\nimport JSONL from './jsonl'\r\nimport * as jsMisc from './misc-js-funcs'\r\nexport * from './misc-js-funcs'\r\nimport tileMap from './tile-map'\r\nexport * from './tile-map'\r\n\r\nexport {\r\n s3,\r\n JSONL,\r\n tileMap\r\n}\r\n\r\nexport default {\r\n s3,\r\n JSONL,\r\n tileMap,\r\n utils: {\r\n ...jsMisc\r\n }\r\n}\r\n", "/* eslint-disable no-console */\r\nimport { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsV2Command, ListObjectsV2CommandInput, DeleteObjectCommand } from \"@aws-sdk/client-s3\";\r\nlet client: S3Client;\r\n\r\nexport interface IS3Config {\r\n region: string;\r\n bucket: string;\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n}\r\n\r\nexport const getClient = ({ region, accessKeyId, secretAccessKey }: IS3Config) => {\r\n if (!client) {\r\n client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });\r\n }\r\n\r\n return client;\r\n};\r\n\r\nexport const putObject = async(config: IS3Config, data: Buffer | string, key: string, contentType?: string) => {\r\n try {\r\n const cl = getClient(config);\r\n\r\n const params: { Bucket: string; Key: string; Body: Buffer | string; ContentType?: string } = {\r\n Bucket: config.bucket,\r\n Key: key,\r\n Body: typeof data === 'string' ? Buffer.from(data, \"utf-8\") : data\r\n };\r\n if(contentType) {\r\n params.ContentType = contentType\r\n }\r\n\r\n return await cl.send(new PutObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not upload json file', { error: e });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const getObject = async(config: IS3Config, key: string) => {\r\n const params = {\r\n Bucket: config.bucket,\r\n Key: key,\r\n };\r\n\r\n try {\r\n const cl = getClient(config);\r\n\r\n return await cl.send(new GetObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not get object from s3', { error: e, params });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const listObjects = async(config: IS3Config, prefix: string, Marker?: string) => {\r\n const params: ListObjectsV2CommandInput = {\r\n Bucket: config.bucket,\r\n Prefix: prefix,\r\n };\r\n if (Marker) {\r\n params.StartAfter = Marker;\r\n }\r\n try {\r\n const cl = getClient(config);\r\n\r\n const response = await cl.send(new ListObjectsV2Command(params));\r\n return { Objects: (response.Contents ?? []), Marker: response.NextContinuationToken };\r\n } catch (e) {\r\n console.error('Could not upload json file', { error: e });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const deleteObject = async(config: IS3Config, Key: string) => {\r\n const params = {\r\n Bucket: config.bucket,\r\n Key,\r\n };\r\n\r\n try {\r\n const cl = getClient(config);\r\n\r\n return await cl.send(new DeleteObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not delete object from s3', { error: e, params });\r\n throw e;\r\n }\r\n};\r\n", "import { EOL } from 'os'\r\n\r\n/**\r\n * made fairly specifically for arrays when dealing with larger qunatities of data that you may need to concat later\r\n */\r\n\r\nexport default {\r\n stringify: (data: any[]): string => {\r\n return data.map((d) => JSON.stringify(d)).join(EOL);\r\n },\r\n\r\n parse: (data: string): any[] => {\r\n return data.split(EOL).map((d, i) => {\r\n try{\r\n return JSON.parse(d);\r\n } catch (e: any) {\r\n console.error('Could not parse JSONL on line: ' + i, { error: e.message, line: i });\r\n }\r\n });\r\n },\r\n}\r\n \r\n", "const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\nconst chunkArray = (source: Array<any>, chunkSize: number = 10) => {\r\n const chunks = source.reduce((resultArray, item, index) => { \r\n const chunkIndex = Math.floor(index/chunkSize)\r\n \r\n if(!resultArray[chunkIndex]) {\r\n resultArray[chunkIndex] = []\r\n }\r\n \r\n resultArray[chunkIndex].push(item)\r\n \r\n return resultArray\r\n }, [])\r\n return chunks\r\n}\r\n\r\nconst settledSeparator = (result: Array<PromiseSettledResult<any>>) => {\r\n const settled = result.filter((r) => r.status === 'fulfilled')\r\n const rejected = result.filter((r) => r.status === 'rejected')\r\n return { settled, rejected, total: result.length }\r\n}\r\n \r\nconst timeFormat = (ms: number) => {\r\n if (ms < 1000) return `${ms} ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)} secs`;\r\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)} mins`;\r\n return `${(ms / 3600000).toFixed(2)} hrs`;\r\n}\r\n\r\nconst timeSinceString = (ms: number) => {\r\n return timeFormat(Date.now() - ms);\r\n}\r\n\r\nconst generateRandomString = (length = 8) => {\r\n return Math.random().toString(36).substring(2, 2 + length);\r\n}\r\n\r\n\r\nexport {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n\r\nexport default {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n", "// --- types ---\n\n/** A 2-D grid of tiles. `T` is the entity type stored per tile. */\nexport type TileMap<T = unknown> = {\n readonly width: number\n readonly height: number\n readonly size: number\n flags: Uint8Array\n entities: Map<number, T[]>\n}\n\n/**\n * A snapshot of a single tile's state.\n * `index` is the flat array position (`y * width + x`).\n */\nexport type TileInfo<T> = {\n readonly index: number\n readonly x: number\n readonly y: number\n flags: number\n entities: T[]\n}\n\n/** Shape used when collecting tiles or entities within a radius. */\nexport type RangeShape = 'square' | 'circle'\n\n/** Return `true` to pass, `false` to fail. Used by `validateTile` and `validateRange`. */\nexport type TileValidator<T> = (tile: TileInfo<T>) => boolean\n\n/**\n * Predefined single-bit flag constants.\n * Combine multiple flags with the bitwise OR operator:\n * ```ts\n * setFlag(map, x, y, TileFlags.BLOCKED | TileFlags.HAZARD)\n * ```\n * You can define additional custom flags as any unused power-of-two number\n * up to `0b10000000` (Uint8 supports 8 independent bits total).\n */\nexport const TileFlags = {\n NONE: 0b00000000,\n BLOCKED: 0b00000001,\n OCCUPIED: 0b00000010,\n VISIBLE: 0b00000100,\n EXPLORED: 0b00001000,\n WATER: 0b00010000,\n HAZARD: 0b00100000,\n} as const\n\n// --- internal helpers ---\n\nconst _idx = (width: number, x: number, y: number): number => y * width + x\n\nconst _inBounds = (width: number, height: number, x: number, y: number): boolean =>\n x >= 0 && x < width && y >= 0 && y < height\n\n// Packed dx/dy pairs for cardinal then diagonal neighbours\nconst _CARDINAL = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1])\nconst _ALL_ADJ = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1])\n\n// --- creation ---\n\n/**\n * Create a new tile map of the given dimensions.\n * All flags start at 0 and no entities are placed.\n * @param width Number of columns.\n * @param height Number of rows.\n * @returns A fresh `TileMap<T>`.\n * @example\n * type Unit = { id: string }\n * const map = createTileMap<Unit>(64, 64)\n */\nexport const createTileMap = <T>(width: number, height: number): TileMap<T> => ({\n width,\n height,\n size: width * height,\n flags: new Uint8Array(width * height),\n entities: new Map(),\n})\n\n// --- tile access ---\n\n/**\n * Convert grid coordinates to a flat array index.\n * Returns `-1` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileIndex = (map: TileMap<unknown>, x: number, y: number): number =>\n _inBounds(map.width, map.height, x, y) ? _idx(map.width, x, y) : -1\n\n/**\n * Return a `TileInfo` snapshot for the tile at `(x, y)`.\n * Returns `null` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileInfo = <T>(map: TileMap<T>, x: number, y: number): TileInfo<T> | null => {\n if (!_inBounds(map.width, map.height, x, y)) return null\n const index = _idx(map.width, x, y)\n return {\n index,\n x,\n y,\n flags: map.flags[index],\n entities: map.entities.get(index) ?? [],\n }\n}\n\n/**\n * Convert a flat array index back to `{ x, y }` grid coordinates.\n * @param map The tile map (used for its `width`).\n * @param index Flat tile index.\n */\nexport const indexToCoords = (map: TileMap<unknown>, index: number): { x: number; y: number } => ({\n x: index % map.width,\n y: (index / map.width) | 0,\n})\n\n// --- flag operations (bitwise, Uint8 supports 8 independent flags) ---\n\n/**\n * Set one or more flags on a tile using bitwise OR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) from `TileFlags` or a custom power-of-two constant.\n * @example\n * setFlag(map, 3, 5, TileFlags.BLOCKED)\n */\nexport const setFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] |= flag\n}\n\n/**\n * Clear one or more flags on a tile using bitwise AND NOT.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to clear.\n */\nexport const clearFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] &= ~flag\n}\n\n/**\n * Toggle one or more flags on a tile using bitwise XOR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to toggle.\n */\nexport const toggleFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] ^= flag\n}\n\n/**\n * Return `true` if **all** supplied flag bits are set on the tile.\n * Returns `false` for out-of-bounds coordinates.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to test.\n * @example\n * if (hasFlag(map, x, y, TileFlags.BLOCKED)) { ... }\n */\nexport const hasFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n return (map.flags[_idx(map.width, x, y)] & flag) !== 0\n}\n\n// --- entity operations ---\n\n/**\n * Add an entity to the tile at `(x, y)`.\n * Returns `false` when the coordinates are out of bounds (entity is not added).\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param entity The entity to place on the tile.\n */\nexport const addEntity = <T>(map: TileMap<T>, x: number, y: number, entity: T): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (bucket) bucket.push(entity)\n else map.entities.set(index, [entity])\n return true\n}\n\n/**\n * Remove the **first** entity on the tile at `(x, y)` for which `predicate` returns `true`.\n * Returns `false` when out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param predicate Selector \u2014 return `true` for the entity to remove.\n * @example\n * removeEntity(map, x, y, e => e.id === 'hero')\n */\nexport const removeEntity = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n predicate: (e: T) => boolean\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (!bucket) return false\n for (let i = 0; i < bucket.length; i++) {\n if (predicate(bucket[i])) {\n bucket.splice(i, 1)\n if (bucket.length === 0) map.entities.delete(index)\n return true\n }\n }\n return false\n}\n\n/**\n * Atomically move the **first** matching entity from one tile to another.\n * Returns `false` when either coordinate is out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param fromX Source column.\n * @param fromY Source row.\n * @param toX Destination column.\n * @param toY Destination row.\n * @param predicate Selector \u2014 return `true` for the entity to move.\n * @example\n * moveEntity(map, 2, 3, 2, 4, e => e.id === 'hero')\n */\nexport const moveEntity = <T>(\n map: TileMap<T>,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n predicate: (e: T) => boolean\n): boolean => {\n const { width, height } = map\n if (!_inBounds(width, height, fromX, fromY) || !_inBounds(width, height, toX, toY)) return false\n const srcIndex = _idx(width, fromX, fromY)\n const src = map.entities.get(srcIndex)\n if (!src) return false\n for (let i = 0; i < src.length; i++) {\n if (predicate(src[i])) {\n const entity = src[i]\n src.splice(i, 1)\n if (src.length === 0) map.entities.delete(srcIndex)\n const dstIndex = _idx(width, toX, toY)\n const dst = map.entities.get(dstIndex)\n if (dst) dst.push(entity)\n else map.entities.set(dstIndex, [entity])\n return true\n }\n }\n return false\n}\n\n/**\n * Return all entities on the tile at `(x, y)`.\n * Returns an empty array for out-of-bounds coordinates or tiles with no entities.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): T[] => {\n if (!_inBounds(map.width, map.height, x, y)) return []\n return map.entities.get(_idx(map.width, x, y)) ?? []\n}\n\n/**\n * Remove all entities from the tile at `(x, y)`.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const clearEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.entities.delete(_idx(map.width, x, y))\n}\n\n// --- adjacency ---\n\n/**\n * Return the flat indices of tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentIndices = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n includeDiagonals = false\n): number[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: number[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) result.push(_idx(width, nx, ny))\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentTiles = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n includeDiagonals = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: TileInfo<T>[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n return result\n}\n\n// --- range queries ---\n\n/**\n * Return the flat indices of all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Circle shape uses integer `dx\u00B2 + dy\u00B2 \u2264 range\u00B2` \u2014 no `Math.sqrt`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getIndicesInRange = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): number[] => {\n const { width, height } = map\n const r2 = range * range\n const result: number[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) result.push(_idx(width, nx, ny))\n }\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getTilesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const r2 = range * range\n const result: TileInfo<T>[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n }\n return result\n}\n\n/**\n * Collect and return every entity on every tile within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Tiles with no entities contribute nothing to the result.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include entities on the center tile itself (default `false`).\n * @example\n * const enemies = getEntitiesInRange(map, heroX, heroY, 3, 'circle')\n */\nexport const getEntitiesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): T[] => {\n const { width, height } = map\n const r2 = range * range\n const result: T[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const bucket = map.entities.get(_idx(width, nx, ny))\n if (bucket) for (let i = 0; i < bucket.length; i++) result.push(bucket[i])\n }\n }\n return result\n}\n\n// --- validation ---\n\n/**\n * Test whether the tile at `(x, y)` is in bounds and passes an optional validator.\n * When no `validator` is provided, returns `true` for any in-bounds coordinate.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param validator Optional predicate; receives a `TileInfo` snapshot.\n * @example\n * const passable = validateTile(map, x, y, t => !(t.flags & TileFlags.BLOCKED))\n */\nexport const validateTile = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n validator?: TileValidator<T>\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n if (!validator) return true\n const index = _idx(map.width, x, y)\n return validator({ index, x, y, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n}\n\n/**\n * Test whether **every** tile within `range` of `(x, y)` passes `validator`.\n * Short-circuits on the first failing tile. Out-of-bounds tiles are skipped entirely.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param validator Predicate; receives a `TileInfo` snapshot.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile in validation (default `false`).\n * @example\n * const areaClear = validateRange(map, x, y, 2, t => t.entities.length === 0)\n */\nexport const validateRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n validator: TileValidator<T>,\n shape: RangeShape = 'square',\n includeOrigin = false\n): boolean => {\n const { width, height } = map\n const r2 = range * range\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const index = _idx(width, nx, ny)\n if (!validator({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })) return false\n }\n }\n return true\n}\n\n// --- spatial / screen-space ---\n\n/**\n * Pixel dimensions of a single tile and an optional world-space origin offset.\n * Create once and reuse; it never mutates.\n *\n * - `tileWidth` / `tileHeight`: pixels per tile (e.g. 32 for a 32\u00D732 sprite sheet).\n * - `originX` / `originY`: world-pixel offset of tile (0, 0)'s top-left corner.\n * Use this to add margins or align the grid inside a larger world.\n *\n * Non-square tiles (e.g. 64\u00D732 isometric projections) are fully supported.\n */\nexport type SpatialConfig = {\n readonly tileWidth: number\n readonly tileHeight: number\n readonly originX: number\n readonly originY: number\n}\n\n/**\n * Fractional tile-grid position for an entity at an arbitrary world coordinate.\n * `tileX` / `tileY` are the integer grid cell; `fracX` / `fracY` are 0..1 offsets\n * within that cell \u2014 useful for smooth movement interpolation and collision checks.\n */\nexport type TilePosition = {\n tileX: number\n tileY: number\n fracX: number\n fracY: number\n}\n\n/**\n * Create a `SpatialConfig`.\n * @param tileWidth Pixels per tile column.\n * @param tileHeight Pixels per tile row.\n * @param originX World-pixel X of the grid's top-left corner (default `0`).\n * @param originY World-pixel Y of the grid's top-left corner (default `0`).\n * @example\n * const spatial = createSpatialConfig(32, 32)\n * const spatial = createSpatialConfig(64, 32, 128, 64) // offset grid\n */\nexport const createSpatialConfig = (\n tileWidth: number,\n tileHeight: number,\n originX = 0,\n originY = 0\n): SpatialConfig => ({ tileWidth, tileHeight, originX, originY })\n\n/**\n * Convert world-pixel coordinates to integer tile grid coordinates.\n * Fractions are floored, so the result is always the tile the point falls inside.\n * Returns `{ x: -1, y: -1 }` when the world position is before the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToTile = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: ((wx - spatial.originX) / spatial.tileWidth) | 0,\n y: ((wy - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **top-left corner**.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX,\n y: ty * spatial.tileHeight + spatial.originY,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **center**.\n * Useful for placing sprites, projectile origins, or distance calculations.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileCenterWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX + (spatial.tileWidth >> 1),\n y: ty * spatial.tileHeight + spatial.originY + (spatial.tileHeight >> 1),\n})\n\n/**\n * Convert screen-pixel coordinates to world-pixel coordinates using the camera offset.\n * The camera position is the world-space coordinate of the screen's top-left corner.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToWorld = (\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: sx + cameraX,\n y: sy + cameraY,\n})\n\n/**\n * Convert world-pixel coordinates to screen-pixel coordinates using the camera offset.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToScreen = (\n cameraX: number,\n cameraY: number,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: wx - cameraX,\n y: wy - cameraY,\n})\n\n/**\n * Convert screen-pixel coordinates directly to tile grid coordinates,\n * accounting for both the camera offset and the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToTile = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0,\n y: ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to screen-pixel coordinates (top-left of the tile),\n * accounting for the camera offset and grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToScreen = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX - cameraX,\n y: ty * spatial.tileHeight + spatial.originY - cameraY,\n})\n\n/**\n * Return the exact fractional tile-grid position for a world coordinate.\n * `tileX` / `tileY` are the integer grid cell the point is inside.\n * `fracX` / `fracY` are 0..1 fractions representing how far into the tile the point is \u2014\n * essential for smooth cross-tile movement, linear interpolation animations, and sub-tile collision.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * // Entity smoothly walking; determine which tile it's in and how far across\n * const pos = worldToTileExact(spatial, entity.x, entity.y)\n * // pos.fracX === 0.5 means entity is horizontally centred in its tile\n */\nexport const worldToTileExact = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TilePosition => {\n const fx = (wx - spatial.originX) / spatial.tileWidth\n const fy = (wy - spatial.originY) / spatial.tileHeight\n const tileX = fx | 0\n const tileY = fy | 0\n return { tileX, tileY, fracX: fx - tileX, fracY: fy - tileY }\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a world-pixel position falls on.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * const tile = getTileAtWorld(map, spatial, entity.x, entity.y)\n * if (tile && tile.flags & TileFlags.HAZARD) takeDamage(entity)\n */\nexport const getTileAtWorld = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TileInfo<T> | null => {\n const tx = ((wx - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((wy - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a screen-pixel position falls on,\n * accounting for the camera offset and grid origin.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n * @example\n * // Mouse click \u2192 tile lookup\n * const tile = getTileAtScreen(map, spatial, camera.x, camera.y, mouseX, mouseY)\n */\nexport const getTileAtScreen = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): TileInfo<T> | null => {\n const tx = ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n// --- default export ---\n\nexport default {\n TileFlags,\n createTileMap,\n getTileIndex,\n getTileInfo,\n indexToCoords,\n setFlag,\n clearFlag,\n toggleFlag,\n hasFlag,\n addEntity,\n removeEntity,\n moveEntity,\n getEntitiesAt,\n clearEntitiesAt,\n getAdjacentIndices,\n getAdjacentTiles,\n getIndicesInRange,\n getTilesInRange,\n getEntitiesInRange,\n validateTile,\n validateRange,\n createSpatialConfig,\n worldToTile,\n tileToWorld,\n tileCenterWorld,\n screenToWorld,\n worldToScreen,\n screenToTile,\n tileToScreen,\n worldToTileExact,\n getTileAtWorld,\n getTileAtScreen,\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import * as s3 from './s3'\r\nexport * from './s3'\r\nimport JSONL from './jsonl'\r\nimport * as jsMisc from './misc-js-funcs'\r\nexport * from './misc-js-funcs'\r\nimport tileMap from './tile-map'\r\nexport * from './tile-map'\r\n\r\nexport {\r\n s3,\r\n JSONL,\r\n tileMap\r\n}\r\n\r\nexport default {\r\n s3,\r\n JSONL,\r\n tileMap,\r\n utils: {\r\n ...jsMisc\r\n }\r\n}\r\n", "/* eslint-disable no-console */\n\nexport interface IS3Config {\n region: string;\n bucket: string;\n accessKeyId: string;\n secretAccessKey: string;\n}\n\ntype S3Module = typeof import('@aws-sdk/client-s3');\nlet _mod: S3Module | null = null;\n\nasync function getModule(): Promise<S3Module> {\n if (!_mod) {\n try {\n _mod = await import('@aws-sdk/client-s3');\n } catch {\n throw new Error(\n '[beardos-toolbox] @aws-sdk/client-s3 is required to use the S3 helpers. ' +\n 'Install it: npm i @aws-sdk/client-s3'\n );\n }\n }\n return _mod;\n}\n\ntype S3ClientInstance = InstanceType<S3Module['S3Client']>;\nlet client: S3ClientInstance;\n\nexport const getClient = async ({ region, accessKeyId, secretAccessKey }: IS3Config): Promise<S3ClientInstance> => {\n if (!client) {\n const { S3Client } = await getModule();\n client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });\n }\n return client;\n};\n\nexport const putObject = async (config: IS3Config, data: Buffer | string, key: string, contentType?: string) => {\n try {\n const { PutObjectCommand } = await getModule();\n const cl = await getClient(config);\n const params: { Bucket: string; Key: string; Body: Buffer | string; ContentType?: string } = {\n Bucket: config.bucket,\n Key: key,\n Body: typeof data === 'string' ? Buffer.from(data, 'utf-8') : data,\n };\n if (contentType) params.ContentType = contentType;\n return await cl.send(new PutObjectCommand(params));\n } catch (e) {\n console.error('Could not upload object', { error: e });\n throw e;\n }\n};\n\nexport const getObject = async (config: IS3Config, key: string) => {\n const params = { Bucket: config.bucket, Key: key };\n try {\n const { GetObjectCommand } = await getModule();\n const cl = await getClient(config);\n return await cl.send(new GetObjectCommand(params));\n } catch (e) {\n console.error('Could not get object from s3', { error: e, params });\n throw e;\n }\n};\n\nexport const listObjects = async (config: IS3Config, prefix: string, Marker?: string) => {\n try {\n const { ListObjectsV2Command } = await getModule();\n const cl = await getClient(config);\n const params: import('@aws-sdk/client-s3').ListObjectsV2CommandInput = {\n Bucket: config.bucket,\n Prefix: prefix,\n ...(Marker ? { StartAfter: Marker } : {}),\n };\n const response = await cl.send(new ListObjectsV2Command(params));\n return { Objects: response.Contents ?? [], Marker: response.NextContinuationToken };\n } catch (e) {\n console.error('Could not list objects', { error: e });\n throw e;\n }\n};\n\nexport const deleteObject = async (config: IS3Config, Key: string) => {\n const params = { Bucket: config.bucket, Key };\n try {\n const { DeleteObjectCommand } = await getModule();\n const cl = await getClient(config);\n return await cl.send(new DeleteObjectCommand(params));\n } catch (e) {\n console.error('Could not delete object from s3', { error: e, params });\n throw e;\n }\n};\n", "import { EOL } from 'os'\r\n\r\n/**\r\n * made fairly specifically for arrays when dealing with larger qunatities of data that you may need to concat later\r\n */\r\n\r\nexport default {\r\n stringify: (data: any[]): string => {\r\n return data.map((d) => JSON.stringify(d)).join(EOL);\r\n },\r\n\r\n parse: (data: string): any[] => {\r\n return data.split(EOL).map((d, i) => {\r\n try{\r\n return JSON.parse(d);\r\n } catch (e: any) {\r\n console.error('Could not parse JSONL on line: ' + i, { error: e.message, line: i });\r\n }\r\n });\r\n },\r\n}\r\n \r\n", "const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\nconst chunkArray = (source: Array<any>, chunkSize: number = 10) => {\r\n const chunks = source.reduce((resultArray, item, index) => { \r\n const chunkIndex = Math.floor(index/chunkSize)\r\n \r\n if(!resultArray[chunkIndex]) {\r\n resultArray[chunkIndex] = []\r\n }\r\n \r\n resultArray[chunkIndex].push(item)\r\n \r\n return resultArray\r\n }, [])\r\n return chunks\r\n}\r\n\r\nconst settledSeparator = (result: Array<PromiseSettledResult<any>>) => {\r\n const settled = result.filter((r) => r.status === 'fulfilled')\r\n const rejected = result.filter((r) => r.status === 'rejected')\r\n return { settled, rejected, total: result.length }\r\n}\r\n \r\nconst timeFormat = (ms: number) => {\r\n if (ms < 1000) return `${ms} ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)} secs`;\r\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)} mins`;\r\n return `${(ms / 3600000).toFixed(2)} hrs`;\r\n}\r\n\r\nconst timeSinceString = (ms: number) => {\r\n return timeFormat(Date.now() - ms);\r\n}\r\n\r\nconst generateRandomString = (length = 8) => {\r\n return Math.random().toString(36).substring(2, 2 + length);\r\n}\r\n\r\n\r\nexport {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n\r\nexport default {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n", "// --- types ---\n\n/** A 2-D grid of tiles. `T` is the entity type stored per tile. */\nexport type TileMap<T = unknown> = {\n readonly width: number\n readonly height: number\n readonly size: number\n flags: Uint8Array\n entities: Map<number, T[]>\n}\n\n/**\n * A snapshot of a single tile's state.\n * `index` is the flat array position (`y * width + x`).\n */\nexport type TileInfo<T> = {\n readonly index: number\n readonly x: number\n readonly y: number\n flags: number\n entities: T[]\n}\n\n/** Shape used when collecting tiles or entities within a radius. */\nexport type RangeShape = 'square' | 'circle'\n\n/** Return `true` to pass, `false` to fail. Used by `validateTile` and `validateRange`. */\nexport type TileValidator<T> = (tile: TileInfo<T>) => boolean\n\n/**\n * Predefined single-bit flag constants.\n * Combine multiple flags with the bitwise OR operator:\n * ```ts\n * setFlag(map, x, y, TileFlags.BLOCKED | TileFlags.HAZARD)\n * ```\n * You can define additional custom flags as any unused power-of-two number\n * up to `0b10000000` (Uint8 supports 8 independent bits total).\n */\nexport const TileFlags = {\n NONE: 0b00000000,\n BLOCKED: 0b00000001,\n OCCUPIED: 0b00000010,\n VISIBLE: 0b00000100,\n EXPLORED: 0b00001000,\n WATER: 0b00010000,\n HAZARD: 0b00100000,\n} as const\n\n// --- internal helpers ---\n\nconst _idx = (width: number, x: number, y: number): number => y * width + x\n\nconst _inBounds = (width: number, height: number, x: number, y: number): boolean =>\n x >= 0 && x < width && y >= 0 && y < height\n\n// Packed dx/dy pairs for cardinal then diagonal neighbours\nconst _CARDINAL = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1])\nconst _ALL_ADJ = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1])\n\n// --- creation ---\n\n/**\n * Create a new tile map of the given dimensions.\n * All flags start at 0 and no entities are placed.\n * @param width Number of columns.\n * @param height Number of rows.\n * @returns A fresh `TileMap<T>`.\n * @example\n * type Unit = { id: string }\n * const map = createTileMap<Unit>(64, 64)\n */\nexport const createTileMap = <T>(width: number, height: number): TileMap<T> => ({\n width,\n height,\n size: width * height,\n flags: new Uint8Array(width * height),\n entities: new Map(),\n})\n\n// --- tile access ---\n\n/**\n * Convert grid coordinates to a flat array index.\n * Returns `-1` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileIndex = (map: TileMap<unknown>, x: number, y: number): number =>\n _inBounds(map.width, map.height, x, y) ? _idx(map.width, x, y) : -1\n\n/**\n * Return a `TileInfo` snapshot for the tile at `(x, y)`.\n * Returns `null` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileInfo = <T>(map: TileMap<T>, x: number, y: number): TileInfo<T> | null => {\n if (!_inBounds(map.width, map.height, x, y)) return null\n const index = _idx(map.width, x, y)\n return {\n index,\n x,\n y,\n flags: map.flags[index],\n entities: map.entities.get(index) ?? [],\n }\n}\n\n/**\n * Convert a flat array index back to `{ x, y }` grid coordinates.\n * @param map The tile map (used for its `width`).\n * @param index Flat tile index.\n */\nexport const indexToCoords = (map: TileMap<unknown>, index: number): { x: number; y: number } => ({\n x: index % map.width,\n y: (index / map.width) | 0,\n})\n\n// --- flag operations (bitwise, Uint8 supports 8 independent flags) ---\n\n/**\n * Set one or more flags on a tile using bitwise OR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) from `TileFlags` or a custom power-of-two constant.\n * @example\n * setFlag(map, 3, 5, TileFlags.BLOCKED)\n */\nexport const setFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] |= flag\n}\n\n/**\n * Clear one or more flags on a tile using bitwise AND NOT.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to clear.\n */\nexport const clearFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] &= ~flag\n}\n\n/**\n * Toggle one or more flags on a tile using bitwise XOR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to toggle.\n */\nexport const toggleFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] ^= flag\n}\n\n/**\n * Return `true` if **all** supplied flag bits are set on the tile.\n * Returns `false` for out-of-bounds coordinates.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to test.\n * @example\n * if (hasFlag(map, x, y, TileFlags.BLOCKED)) { ... }\n */\nexport const hasFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n return (map.flags[_idx(map.width, x, y)] & flag) !== 0\n}\n\n// --- entity operations ---\n\n/**\n * Add an entity to the tile at `(x, y)`.\n * Returns `false` when the coordinates are out of bounds (entity is not added).\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param entity The entity to place on the tile.\n */\nexport const addEntity = <T>(map: TileMap<T>, x: number, y: number, entity: T): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (bucket) bucket.push(entity)\n else map.entities.set(index, [entity])\n return true\n}\n\n/**\n * Remove the **first** entity on the tile at `(x, y)` for which `predicate` returns `true`.\n * Returns `false` when out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param predicate Selector \u2014 return `true` for the entity to remove.\n * @example\n * removeEntity(map, x, y, e => e.id === 'hero')\n */\nexport const removeEntity = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n predicate: (e: T) => boolean\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (!bucket) return false\n for (let i = 0; i < bucket.length; i++) {\n if (predicate(bucket[i])) {\n bucket.splice(i, 1)\n if (bucket.length === 0) map.entities.delete(index)\n return true\n }\n }\n return false\n}\n\n/**\n * Atomically move the **first** matching entity from one tile to another.\n * Returns `false` when either coordinate is out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param fromX Source column.\n * @param fromY Source row.\n * @param toX Destination column.\n * @param toY Destination row.\n * @param predicate Selector \u2014 return `true` for the entity to move.\n * @example\n * moveEntity(map, 2, 3, 2, 4, e => e.id === 'hero')\n */\nexport const moveEntity = <T>(\n map: TileMap<T>,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n predicate: (e: T) => boolean\n): boolean => {\n const { width, height } = map\n if (!_inBounds(width, height, fromX, fromY) || !_inBounds(width, height, toX, toY)) return false\n const srcIndex = _idx(width, fromX, fromY)\n const src = map.entities.get(srcIndex)\n if (!src) return false\n for (let i = 0; i < src.length; i++) {\n if (predicate(src[i])) {\n const entity = src[i]\n src.splice(i, 1)\n if (src.length === 0) map.entities.delete(srcIndex)\n const dstIndex = _idx(width, toX, toY)\n const dst = map.entities.get(dstIndex)\n if (dst) dst.push(entity)\n else map.entities.set(dstIndex, [entity])\n return true\n }\n }\n return false\n}\n\n/**\n * Return all entities on the tile at `(x, y)`.\n * Returns an empty array for out-of-bounds coordinates or tiles with no entities.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): T[] => {\n if (!_inBounds(map.width, map.height, x, y)) return []\n return map.entities.get(_idx(map.width, x, y)) ?? []\n}\n\n/**\n * Remove all entities from the tile at `(x, y)`.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const clearEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.entities.delete(_idx(map.width, x, y))\n}\n\n// --- adjacency ---\n\n/**\n * Return the flat indices of tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentIndices = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n includeDiagonals = false\n): number[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: number[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) result.push(_idx(width, nx, ny))\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentTiles = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n includeDiagonals = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: TileInfo<T>[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n return result\n}\n\n// --- range queries ---\n\n/**\n * Return the flat indices of all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Circle shape uses integer `dx\u00B2 + dy\u00B2 \u2264 range\u00B2` \u2014 no `Math.sqrt`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getIndicesInRange = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): number[] => {\n const { width, height } = map\n const r2 = range * range\n const result: number[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) result.push(_idx(width, nx, ny))\n }\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getTilesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const r2 = range * range\n const result: TileInfo<T>[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n }\n return result\n}\n\n/**\n * Collect and return every entity on every tile within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Tiles with no entities contribute nothing to the result.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include entities on the center tile itself (default `false`).\n * @example\n * const enemies = getEntitiesInRange(map, heroX, heroY, 3, 'circle')\n */\nexport const getEntitiesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): T[] => {\n const { width, height } = map\n const r2 = range * range\n const result: T[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const bucket = map.entities.get(_idx(width, nx, ny))\n if (bucket) for (let i = 0; i < bucket.length; i++) result.push(bucket[i])\n }\n }\n return result\n}\n\n// --- validation ---\n\n/**\n * Test whether the tile at `(x, y)` is in bounds and passes an optional validator.\n * When no `validator` is provided, returns `true` for any in-bounds coordinate.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param validator Optional predicate; receives a `TileInfo` snapshot.\n * @example\n * const passable = validateTile(map, x, y, t => !(t.flags & TileFlags.BLOCKED))\n */\nexport const validateTile = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n validator?: TileValidator<T>\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n if (!validator) return true\n const index = _idx(map.width, x, y)\n return validator({ index, x, y, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n}\n\n/**\n * Test whether **every** tile within `range` of `(x, y)` passes `validator`.\n * Short-circuits on the first failing tile. Out-of-bounds tiles are skipped entirely.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param validator Predicate; receives a `TileInfo` snapshot.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile in validation (default `false`).\n * @example\n * const areaClear = validateRange(map, x, y, 2, t => t.entities.length === 0)\n */\nexport const validateRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n validator: TileValidator<T>,\n shape: RangeShape = 'square',\n includeOrigin = false\n): boolean => {\n const { width, height } = map\n const r2 = range * range\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const index = _idx(width, nx, ny)\n if (!validator({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })) return false\n }\n }\n return true\n}\n\n// --- spatial / screen-space ---\n\n/**\n * Pixel dimensions of a single tile and an optional world-space origin offset.\n * Create once and reuse; it never mutates.\n *\n * - `tileWidth` / `tileHeight`: pixels per tile (e.g. 32 for a 32\u00D732 sprite sheet).\n * - `originX` / `originY`: world-pixel offset of tile (0, 0)'s top-left corner.\n * Use this to add margins or align the grid inside a larger world.\n *\n * Non-square tiles (e.g. 64\u00D732 isometric projections) are fully supported.\n */\nexport type SpatialConfig = {\n readonly tileWidth: number\n readonly tileHeight: number\n readonly originX: number\n readonly originY: number\n}\n\n/**\n * Fractional tile-grid position for an entity at an arbitrary world coordinate.\n * `tileX` / `tileY` are the integer grid cell; `fracX` / `fracY` are 0..1 offsets\n * within that cell \u2014 useful for smooth movement interpolation and collision checks.\n */\nexport type TilePosition = {\n tileX: number\n tileY: number\n fracX: number\n fracY: number\n}\n\n/**\n * Create a `SpatialConfig`.\n * @param tileWidth Pixels per tile column.\n * @param tileHeight Pixels per tile row.\n * @param originX World-pixel X of the grid's top-left corner (default `0`).\n * @param originY World-pixel Y of the grid's top-left corner (default `0`).\n * @example\n * const spatial = createSpatialConfig(32, 32)\n * const spatial = createSpatialConfig(64, 32, 128, 64) // offset grid\n */\nexport const createSpatialConfig = (\n tileWidth: number,\n tileHeight: number,\n originX = 0,\n originY = 0\n): SpatialConfig => ({ tileWidth, tileHeight, originX, originY })\n\n/**\n * Convert world-pixel coordinates to integer tile grid coordinates.\n * Fractions are floored, so the result is always the tile the point falls inside.\n * Returns `{ x: -1, y: -1 }` when the world position is before the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToTile = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: ((wx - spatial.originX) / spatial.tileWidth) | 0,\n y: ((wy - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **top-left corner**.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX,\n y: ty * spatial.tileHeight + spatial.originY,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **center**.\n * Useful for placing sprites, projectile origins, or distance calculations.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileCenterWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX + (spatial.tileWidth >> 1),\n y: ty * spatial.tileHeight + spatial.originY + (spatial.tileHeight >> 1),\n})\n\n/**\n * Convert screen-pixel coordinates to world-pixel coordinates using the camera offset.\n * The camera position is the world-space coordinate of the screen's top-left corner.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToWorld = (\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: sx + cameraX,\n y: sy + cameraY,\n})\n\n/**\n * Convert world-pixel coordinates to screen-pixel coordinates using the camera offset.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToScreen = (\n cameraX: number,\n cameraY: number,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: wx - cameraX,\n y: wy - cameraY,\n})\n\n/**\n * Convert screen-pixel coordinates directly to tile grid coordinates,\n * accounting for both the camera offset and the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToTile = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0,\n y: ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to screen-pixel coordinates (top-left of the tile),\n * accounting for the camera offset and grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToScreen = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX - cameraX,\n y: ty * spatial.tileHeight + spatial.originY - cameraY,\n})\n\n/**\n * Return the exact fractional tile-grid position for a world coordinate.\n * `tileX` / `tileY` are the integer grid cell the point is inside.\n * `fracX` / `fracY` are 0..1 fractions representing how far into the tile the point is \u2014\n * essential for smooth cross-tile movement, linear interpolation animations, and sub-tile collision.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * // Entity smoothly walking; determine which tile it's in and how far across\n * const pos = worldToTileExact(spatial, entity.x, entity.y)\n * // pos.fracX === 0.5 means entity is horizontally centred in its tile\n */\nexport const worldToTileExact = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TilePosition => {\n const fx = (wx - spatial.originX) / spatial.tileWidth\n const fy = (wy - spatial.originY) / spatial.tileHeight\n const tileX = fx | 0\n const tileY = fy | 0\n return { tileX, tileY, fracX: fx - tileX, fracY: fy - tileY }\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a world-pixel position falls on.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * const tile = getTileAtWorld(map, spatial, entity.x, entity.y)\n * if (tile && tile.flags & TileFlags.HAZARD) takeDamage(entity)\n */\nexport const getTileAtWorld = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TileInfo<T> | null => {\n const tx = ((wx - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((wy - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a screen-pixel position falls on,\n * accounting for the camera offset and grid origin.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n * @example\n * // Mouse click \u2192 tile lookup\n * const tile = getTileAtScreen(map, spatial, camera.x, camera.y, mouseX, mouseY)\n */\nexport const getTileAtScreen = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): TileInfo<T> | null => {\n const tx = ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n// --- default export ---\n\nexport default {\n TileFlags,\n createTileMap,\n getTileIndex,\n getTileInfo,\n indexToCoords,\n setFlag,\n clearFlag,\n toggleFlag,\n hasFlag,\n addEntity,\n removeEntity,\n moveEntity,\n getEntitiesAt,\n clearEntitiesAt,\n getAdjacentIndices,\n getAdjacentTiles,\n getIndicesInRange,\n getTilesInRange,\n getEntitiesInRange,\n validateTile,\n validateRange,\n createSpatialConfig,\n worldToTile,\n tileToWorld,\n tileCenterWorld,\n screenToWorld,\n worldToScreen,\n screenToTile,\n tileToScreen,\n worldToTileExact,\n getTileAtWorld,\n getTileAtScreen,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -13,38 +13,48 @@ __export(s3_exports, {
|
|
|
13
13
|
listObjects: () => listObjects,
|
|
14
14
|
putObject: () => putObject
|
|
15
15
|
});
|
|
16
|
-
|
|
16
|
+
var _mod = null;
|
|
17
|
+
async function getModule() {
|
|
18
|
+
if (!_mod) {
|
|
19
|
+
try {
|
|
20
|
+
_mod = await import("@aws-sdk/client-s3");
|
|
21
|
+
} catch {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"[beardos-toolbox] @aws-sdk/client-s3 is required to use the S3 helpers. Install it: npm i @aws-sdk/client-s3"
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return _mod;
|
|
28
|
+
}
|
|
17
29
|
var client;
|
|
18
|
-
var getClient = ({ region, accessKeyId, secretAccessKey }) => {
|
|
30
|
+
var getClient = async ({ region, accessKeyId, secretAccessKey }) => {
|
|
19
31
|
if (!client) {
|
|
32
|
+
const { S3Client } = await getModule();
|
|
20
33
|
client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });
|
|
21
34
|
}
|
|
22
35
|
return client;
|
|
23
36
|
};
|
|
24
37
|
var putObject = async (config, data, key, contentType) => {
|
|
25
38
|
try {
|
|
26
|
-
const
|
|
39
|
+
const { PutObjectCommand } = await getModule();
|
|
40
|
+
const cl = await getClient(config);
|
|
27
41
|
const params = {
|
|
28
42
|
Bucket: config.bucket,
|
|
29
43
|
Key: key,
|
|
30
44
|
Body: typeof data === "string" ? Buffer.from(data, "utf-8") : data
|
|
31
45
|
};
|
|
32
|
-
if (contentType)
|
|
33
|
-
params.ContentType = contentType;
|
|
34
|
-
}
|
|
46
|
+
if (contentType) params.ContentType = contentType;
|
|
35
47
|
return await cl.send(new PutObjectCommand(params));
|
|
36
48
|
} catch (e) {
|
|
37
|
-
console.error("Could not upload
|
|
49
|
+
console.error("Could not upload object", { error: e });
|
|
38
50
|
throw e;
|
|
39
51
|
}
|
|
40
52
|
};
|
|
41
53
|
var getObject = async (config, key) => {
|
|
42
|
-
const params = {
|
|
43
|
-
Bucket: config.bucket,
|
|
44
|
-
Key: key
|
|
45
|
-
};
|
|
54
|
+
const params = { Bucket: config.bucket, Key: key };
|
|
46
55
|
try {
|
|
47
|
-
const
|
|
56
|
+
const { GetObjectCommand } = await getModule();
|
|
57
|
+
const cl = await getClient(config);
|
|
48
58
|
return await cl.send(new GetObjectCommand(params));
|
|
49
59
|
} catch (e) {
|
|
50
60
|
console.error("Could not get object from s3", { error: e, params });
|
|
@@ -52,29 +62,26 @@ var getObject = async (config, key) => {
|
|
|
52
62
|
}
|
|
53
63
|
};
|
|
54
64
|
var listObjects = async (config, prefix, Marker) => {
|
|
55
|
-
const params = {
|
|
56
|
-
Bucket: config.bucket,
|
|
57
|
-
Prefix: prefix
|
|
58
|
-
};
|
|
59
|
-
if (Marker) {
|
|
60
|
-
params.StartAfter = Marker;
|
|
61
|
-
}
|
|
62
65
|
try {
|
|
63
|
-
const
|
|
66
|
+
const { ListObjectsV2Command } = await getModule();
|
|
67
|
+
const cl = await getClient(config);
|
|
68
|
+
const params = {
|
|
69
|
+
Bucket: config.bucket,
|
|
70
|
+
Prefix: prefix,
|
|
71
|
+
...Marker ? { StartAfter: Marker } : {}
|
|
72
|
+
};
|
|
64
73
|
const response = await cl.send(new ListObjectsV2Command(params));
|
|
65
74
|
return { Objects: response.Contents ?? [], Marker: response.NextContinuationToken };
|
|
66
75
|
} catch (e) {
|
|
67
|
-
console.error("Could not
|
|
76
|
+
console.error("Could not list objects", { error: e });
|
|
68
77
|
throw e;
|
|
69
78
|
}
|
|
70
79
|
};
|
|
71
80
|
var deleteObject = async (config, Key) => {
|
|
72
|
-
const params = {
|
|
73
|
-
Bucket: config.bucket,
|
|
74
|
-
Key
|
|
75
|
-
};
|
|
81
|
+
const params = { Bucket: config.bucket, Key };
|
|
76
82
|
try {
|
|
77
|
-
const
|
|
83
|
+
const { DeleteObjectCommand } = await getModule();
|
|
84
|
+
const cl = await getClient(config);
|
|
78
85
|
return await cl.send(new DeleteObjectCommand(params));
|
|
79
86
|
} catch (e) {
|
|
80
87
|
console.error("Could not delete object from s3", { error: e, params });
|
package/dist/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../s3.ts", "../jsonl.ts", "../misc-js-funcs.ts", "../tile-map.ts", "../index.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-console */\r\nimport { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsV2Command, ListObjectsV2CommandInput, DeleteObjectCommand } from \"@aws-sdk/client-s3\";\r\nlet client: S3Client;\r\n\r\nexport interface IS3Config {\r\n region: string;\r\n bucket: string;\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n}\r\n\r\nexport const getClient = ({ region, accessKeyId, secretAccessKey }: IS3Config) => {\r\n if (!client) {\r\n client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });\r\n }\r\n\r\n return client;\r\n};\r\n\r\nexport const putObject = async(config: IS3Config, data: Buffer | string, key: string, contentType?: string) => {\r\n try {\r\n const cl = getClient(config);\r\n\r\n const params: { Bucket: string; Key: string; Body: Buffer | string; ContentType?: string } = {\r\n Bucket: config.bucket,\r\n Key: key,\r\n Body: typeof data === 'string' ? Buffer.from(data, \"utf-8\") : data\r\n };\r\n if(contentType) {\r\n params.ContentType = contentType\r\n }\r\n\r\n return await cl.send(new PutObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not upload json file', { error: e });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const getObject = async(config: IS3Config, key: string) => {\r\n const params = {\r\n Bucket: config.bucket,\r\n Key: key,\r\n };\r\n\r\n try {\r\n const cl = getClient(config);\r\n\r\n return await cl.send(new GetObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not get object from s3', { error: e, params });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const listObjects = async(config: IS3Config, prefix: string, Marker?: string) => {\r\n const params: ListObjectsV2CommandInput = {\r\n Bucket: config.bucket,\r\n Prefix: prefix,\r\n };\r\n if (Marker) {\r\n params.StartAfter = Marker;\r\n }\r\n try {\r\n const cl = getClient(config);\r\n\r\n const response = await cl.send(new ListObjectsV2Command(params));\r\n return { Objects: (response.Contents ?? []), Marker: response.NextContinuationToken };\r\n } catch (e) {\r\n console.error('Could not upload json file', { error: e });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const deleteObject = async(config: IS3Config, Key: string) => {\r\n const params = {\r\n Bucket: config.bucket,\r\n Key,\r\n };\r\n\r\n try {\r\n const cl = getClient(config);\r\n\r\n return await cl.send(new DeleteObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not delete object from s3', { error: e, params });\r\n throw e;\r\n }\r\n};\r\n", "import { EOL } from 'os'\r\n\r\n/**\r\n * made fairly specifically for arrays when dealing with larger qunatities of data that you may need to concat later\r\n */\r\n\r\nexport default {\r\n stringify: (data: any[]): string => {\r\n return data.map((d) => JSON.stringify(d)).join(EOL);\r\n },\r\n\r\n parse: (data: string): any[] => {\r\n return data.split(EOL).map((d, i) => {\r\n try{\r\n return JSON.parse(d);\r\n } catch (e: any) {\r\n console.error('Could not parse JSONL on line: ' + i, { error: e.message, line: i });\r\n }\r\n });\r\n },\r\n}\r\n \r\n", "const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\nconst chunkArray = (source: Array<any>, chunkSize: number = 10) => {\r\n const chunks = source.reduce((resultArray, item, index) => { \r\n const chunkIndex = Math.floor(index/chunkSize)\r\n \r\n if(!resultArray[chunkIndex]) {\r\n resultArray[chunkIndex] = []\r\n }\r\n \r\n resultArray[chunkIndex].push(item)\r\n \r\n return resultArray\r\n }, [])\r\n return chunks\r\n}\r\n\r\nconst settledSeparator = (result: Array<PromiseSettledResult<any>>) => {\r\n const settled = result.filter((r) => r.status === 'fulfilled')\r\n const rejected = result.filter((r) => r.status === 'rejected')\r\n return { settled, rejected, total: result.length }\r\n}\r\n \r\nconst timeFormat = (ms: number) => {\r\n if (ms < 1000) return `${ms} ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)} secs`;\r\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)} mins`;\r\n return `${(ms / 3600000).toFixed(2)} hrs`;\r\n}\r\n\r\nconst timeSinceString = (ms: number) => {\r\n return timeFormat(Date.now() - ms);\r\n}\r\n\r\nconst generateRandomString = (length = 8) => {\r\n return Math.random().toString(36).substring(2, 2 + length);\r\n}\r\n\r\n\r\nexport {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n\r\nexport default {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n", "// --- types ---\n\n/** A 2-D grid of tiles. `T` is the entity type stored per tile. */\nexport type TileMap<T = unknown> = {\n readonly width: number\n readonly height: number\n readonly size: number\n flags: Uint8Array\n entities: Map<number, T[]>\n}\n\n/**\n * A snapshot of a single tile's state.\n * `index` is the flat array position (`y * width + x`).\n */\nexport type TileInfo<T> = {\n readonly index: number\n readonly x: number\n readonly y: number\n flags: number\n entities: T[]\n}\n\n/** Shape used when collecting tiles or entities within a radius. */\nexport type RangeShape = 'square' | 'circle'\n\n/** Return `true` to pass, `false` to fail. Used by `validateTile` and `validateRange`. */\nexport type TileValidator<T> = (tile: TileInfo<T>) => boolean\n\n/**\n * Predefined single-bit flag constants.\n * Combine multiple flags with the bitwise OR operator:\n * ```ts\n * setFlag(map, x, y, TileFlags.BLOCKED | TileFlags.HAZARD)\n * ```\n * You can define additional custom flags as any unused power-of-two number\n * up to `0b10000000` (Uint8 supports 8 independent bits total).\n */\nexport const TileFlags = {\n NONE: 0b00000000,\n BLOCKED: 0b00000001,\n OCCUPIED: 0b00000010,\n VISIBLE: 0b00000100,\n EXPLORED: 0b00001000,\n WATER: 0b00010000,\n HAZARD: 0b00100000,\n} as const\n\n// --- internal helpers ---\n\nconst _idx = (width: number, x: number, y: number): number => y * width + x\n\nconst _inBounds = (width: number, height: number, x: number, y: number): boolean =>\n x >= 0 && x < width && y >= 0 && y < height\n\n// Packed dx/dy pairs for cardinal then diagonal neighbours\nconst _CARDINAL = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1])\nconst _ALL_ADJ = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1])\n\n// --- creation ---\n\n/**\n * Create a new tile map of the given dimensions.\n * All flags start at 0 and no entities are placed.\n * @param width Number of columns.\n * @param height Number of rows.\n * @returns A fresh `TileMap<T>`.\n * @example\n * type Unit = { id: string }\n * const map = createTileMap<Unit>(64, 64)\n */\nexport const createTileMap = <T>(width: number, height: number): TileMap<T> => ({\n width,\n height,\n size: width * height,\n flags: new Uint8Array(width * height),\n entities: new Map(),\n})\n\n// --- tile access ---\n\n/**\n * Convert grid coordinates to a flat array index.\n * Returns `-1` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileIndex = (map: TileMap<unknown>, x: number, y: number): number =>\n _inBounds(map.width, map.height, x, y) ? _idx(map.width, x, y) : -1\n\n/**\n * Return a `TileInfo` snapshot for the tile at `(x, y)`.\n * Returns `null` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileInfo = <T>(map: TileMap<T>, x: number, y: number): TileInfo<T> | null => {\n if (!_inBounds(map.width, map.height, x, y)) return null\n const index = _idx(map.width, x, y)\n return {\n index,\n x,\n y,\n flags: map.flags[index],\n entities: map.entities.get(index) ?? [],\n }\n}\n\n/**\n * Convert a flat array index back to `{ x, y }` grid coordinates.\n * @param map The tile map (used for its `width`).\n * @param index Flat tile index.\n */\nexport const indexToCoords = (map: TileMap<unknown>, index: number): { x: number; y: number } => ({\n x: index % map.width,\n y: (index / map.width) | 0,\n})\n\n// --- flag operations (bitwise, Uint8 supports 8 independent flags) ---\n\n/**\n * Set one or more flags on a tile using bitwise OR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) from `TileFlags` or a custom power-of-two constant.\n * @example\n * setFlag(map, 3, 5, TileFlags.BLOCKED)\n */\nexport const setFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] |= flag\n}\n\n/**\n * Clear one or more flags on a tile using bitwise AND NOT.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to clear.\n */\nexport const clearFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] &= ~flag\n}\n\n/**\n * Toggle one or more flags on a tile using bitwise XOR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to toggle.\n */\nexport const toggleFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] ^= flag\n}\n\n/**\n * Return `true` if **all** supplied flag bits are set on the tile.\n * Returns `false` for out-of-bounds coordinates.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to test.\n * @example\n * if (hasFlag(map, x, y, TileFlags.BLOCKED)) { ... }\n */\nexport const hasFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n return (map.flags[_idx(map.width, x, y)] & flag) !== 0\n}\n\n// --- entity operations ---\n\n/**\n * Add an entity to the tile at `(x, y)`.\n * Returns `false` when the coordinates are out of bounds (entity is not added).\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param entity The entity to place on the tile.\n */\nexport const addEntity = <T>(map: TileMap<T>, x: number, y: number, entity: T): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (bucket) bucket.push(entity)\n else map.entities.set(index, [entity])\n return true\n}\n\n/**\n * Remove the **first** entity on the tile at `(x, y)` for which `predicate` returns `true`.\n * Returns `false` when out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param predicate Selector \u2014 return `true` for the entity to remove.\n * @example\n * removeEntity(map, x, y, e => e.id === 'hero')\n */\nexport const removeEntity = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n predicate: (e: T) => boolean\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (!bucket) return false\n for (let i = 0; i < bucket.length; i++) {\n if (predicate(bucket[i])) {\n bucket.splice(i, 1)\n if (bucket.length === 0) map.entities.delete(index)\n return true\n }\n }\n return false\n}\n\n/**\n * Atomically move the **first** matching entity from one tile to another.\n * Returns `false` when either coordinate is out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param fromX Source column.\n * @param fromY Source row.\n * @param toX Destination column.\n * @param toY Destination row.\n * @param predicate Selector \u2014 return `true` for the entity to move.\n * @example\n * moveEntity(map, 2, 3, 2, 4, e => e.id === 'hero')\n */\nexport const moveEntity = <T>(\n map: TileMap<T>,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n predicate: (e: T) => boolean\n): boolean => {\n const { width, height } = map\n if (!_inBounds(width, height, fromX, fromY) || !_inBounds(width, height, toX, toY)) return false\n const srcIndex = _idx(width, fromX, fromY)\n const src = map.entities.get(srcIndex)\n if (!src) return false\n for (let i = 0; i < src.length; i++) {\n if (predicate(src[i])) {\n const entity = src[i]\n src.splice(i, 1)\n if (src.length === 0) map.entities.delete(srcIndex)\n const dstIndex = _idx(width, toX, toY)\n const dst = map.entities.get(dstIndex)\n if (dst) dst.push(entity)\n else map.entities.set(dstIndex, [entity])\n return true\n }\n }\n return false\n}\n\n/**\n * Return all entities on the tile at `(x, y)`.\n * Returns an empty array for out-of-bounds coordinates or tiles with no entities.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): T[] => {\n if (!_inBounds(map.width, map.height, x, y)) return []\n return map.entities.get(_idx(map.width, x, y)) ?? []\n}\n\n/**\n * Remove all entities from the tile at `(x, y)`.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const clearEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.entities.delete(_idx(map.width, x, y))\n}\n\n// --- adjacency ---\n\n/**\n * Return the flat indices of tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentIndices = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n includeDiagonals = false\n): number[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: number[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) result.push(_idx(width, nx, ny))\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentTiles = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n includeDiagonals = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: TileInfo<T>[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n return result\n}\n\n// --- range queries ---\n\n/**\n * Return the flat indices of all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Circle shape uses integer `dx\u00B2 + dy\u00B2 \u2264 range\u00B2` \u2014 no `Math.sqrt`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getIndicesInRange = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): number[] => {\n const { width, height } = map\n const r2 = range * range\n const result: number[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) result.push(_idx(width, nx, ny))\n }\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getTilesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const r2 = range * range\n const result: TileInfo<T>[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n }\n return result\n}\n\n/**\n * Collect and return every entity on every tile within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Tiles with no entities contribute nothing to the result.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include entities on the center tile itself (default `false`).\n * @example\n * const enemies = getEntitiesInRange(map, heroX, heroY, 3, 'circle')\n */\nexport const getEntitiesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): T[] => {\n const { width, height } = map\n const r2 = range * range\n const result: T[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const bucket = map.entities.get(_idx(width, nx, ny))\n if (bucket) for (let i = 0; i < bucket.length; i++) result.push(bucket[i])\n }\n }\n return result\n}\n\n// --- validation ---\n\n/**\n * Test whether the tile at `(x, y)` is in bounds and passes an optional validator.\n * When no `validator` is provided, returns `true` for any in-bounds coordinate.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param validator Optional predicate; receives a `TileInfo` snapshot.\n * @example\n * const passable = validateTile(map, x, y, t => !(t.flags & TileFlags.BLOCKED))\n */\nexport const validateTile = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n validator?: TileValidator<T>\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n if (!validator) return true\n const index = _idx(map.width, x, y)\n return validator({ index, x, y, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n}\n\n/**\n * Test whether **every** tile within `range` of `(x, y)` passes `validator`.\n * Short-circuits on the first failing tile. Out-of-bounds tiles are skipped entirely.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param validator Predicate; receives a `TileInfo` snapshot.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile in validation (default `false`).\n * @example\n * const areaClear = validateRange(map, x, y, 2, t => t.entities.length === 0)\n */\nexport const validateRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n validator: TileValidator<T>,\n shape: RangeShape = 'square',\n includeOrigin = false\n): boolean => {\n const { width, height } = map\n const r2 = range * range\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const index = _idx(width, nx, ny)\n if (!validator({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })) return false\n }\n }\n return true\n}\n\n// --- spatial / screen-space ---\n\n/**\n * Pixel dimensions of a single tile and an optional world-space origin offset.\n * Create once and reuse; it never mutates.\n *\n * - `tileWidth` / `tileHeight`: pixels per tile (e.g. 32 for a 32\u00D732 sprite sheet).\n * - `originX` / `originY`: world-pixel offset of tile (0, 0)'s top-left corner.\n * Use this to add margins or align the grid inside a larger world.\n *\n * Non-square tiles (e.g. 64\u00D732 isometric projections) are fully supported.\n */\nexport type SpatialConfig = {\n readonly tileWidth: number\n readonly tileHeight: number\n readonly originX: number\n readonly originY: number\n}\n\n/**\n * Fractional tile-grid position for an entity at an arbitrary world coordinate.\n * `tileX` / `tileY` are the integer grid cell; `fracX` / `fracY` are 0..1 offsets\n * within that cell \u2014 useful for smooth movement interpolation and collision checks.\n */\nexport type TilePosition = {\n tileX: number\n tileY: number\n fracX: number\n fracY: number\n}\n\n/**\n * Create a `SpatialConfig`.\n * @param tileWidth Pixels per tile column.\n * @param tileHeight Pixels per tile row.\n * @param originX World-pixel X of the grid's top-left corner (default `0`).\n * @param originY World-pixel Y of the grid's top-left corner (default `0`).\n * @example\n * const spatial = createSpatialConfig(32, 32)\n * const spatial = createSpatialConfig(64, 32, 128, 64) // offset grid\n */\nexport const createSpatialConfig = (\n tileWidth: number,\n tileHeight: number,\n originX = 0,\n originY = 0\n): SpatialConfig => ({ tileWidth, tileHeight, originX, originY })\n\n/**\n * Convert world-pixel coordinates to integer tile grid coordinates.\n * Fractions are floored, so the result is always the tile the point falls inside.\n * Returns `{ x: -1, y: -1 }` when the world position is before the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToTile = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: ((wx - spatial.originX) / spatial.tileWidth) | 0,\n y: ((wy - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **top-left corner**.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX,\n y: ty * spatial.tileHeight + spatial.originY,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **center**.\n * Useful for placing sprites, projectile origins, or distance calculations.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileCenterWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX + (spatial.tileWidth >> 1),\n y: ty * spatial.tileHeight + spatial.originY + (spatial.tileHeight >> 1),\n})\n\n/**\n * Convert screen-pixel coordinates to world-pixel coordinates using the camera offset.\n * The camera position is the world-space coordinate of the screen's top-left corner.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToWorld = (\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: sx + cameraX,\n y: sy + cameraY,\n})\n\n/**\n * Convert world-pixel coordinates to screen-pixel coordinates using the camera offset.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToScreen = (\n cameraX: number,\n cameraY: number,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: wx - cameraX,\n y: wy - cameraY,\n})\n\n/**\n * Convert screen-pixel coordinates directly to tile grid coordinates,\n * accounting for both the camera offset and the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToTile = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0,\n y: ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to screen-pixel coordinates (top-left of the tile),\n * accounting for the camera offset and grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToScreen = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX - cameraX,\n y: ty * spatial.tileHeight + spatial.originY - cameraY,\n})\n\n/**\n * Return the exact fractional tile-grid position for a world coordinate.\n * `tileX` / `tileY` are the integer grid cell the point is inside.\n * `fracX` / `fracY` are 0..1 fractions representing how far into the tile the point is \u2014\n * essential for smooth cross-tile movement, linear interpolation animations, and sub-tile collision.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * // Entity smoothly walking; determine which tile it's in and how far across\n * const pos = worldToTileExact(spatial, entity.x, entity.y)\n * // pos.fracX === 0.5 means entity is horizontally centred in its tile\n */\nexport const worldToTileExact = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TilePosition => {\n const fx = (wx - spatial.originX) / spatial.tileWidth\n const fy = (wy - spatial.originY) / spatial.tileHeight\n const tileX = fx | 0\n const tileY = fy | 0\n return { tileX, tileY, fracX: fx - tileX, fracY: fy - tileY }\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a world-pixel position falls on.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * const tile = getTileAtWorld(map, spatial, entity.x, entity.y)\n * if (tile && tile.flags & TileFlags.HAZARD) takeDamage(entity)\n */\nexport const getTileAtWorld = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TileInfo<T> | null => {\n const tx = ((wx - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((wy - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a screen-pixel position falls on,\n * accounting for the camera offset and grid origin.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n * @example\n * // Mouse click \u2192 tile lookup\n * const tile = getTileAtScreen(map, spatial, camera.x, camera.y, mouseX, mouseY)\n */\nexport const getTileAtScreen = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): TileInfo<T> | null => {\n const tx = ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n// --- default export ---\n\nexport default {\n TileFlags,\n createTileMap,\n getTileIndex,\n getTileInfo,\n indexToCoords,\n setFlag,\n clearFlag,\n toggleFlag,\n hasFlag,\n addEntity,\n removeEntity,\n moveEntity,\n getEntitiesAt,\n clearEntitiesAt,\n getAdjacentIndices,\n getAdjacentTiles,\n getIndicesInRange,\n getTilesInRange,\n getEntitiesInRange,\n validateTile,\n validateRange,\n createSpatialConfig,\n worldToTile,\n tileToWorld,\n tileCenterWorld,\n screenToWorld,\n worldToScreen,\n screenToTile,\n tileToScreen,\n worldToTileExact,\n getTileAtWorld,\n getTileAtScreen,\n}\n", "import * as s3 from './s3'\r\nexport * from './s3'\r\nimport JSONL from './jsonl'\r\nimport * as jsMisc from './misc-js-funcs'\r\nexport * from './misc-js-funcs'\r\nimport tileMap from './tile-map'\r\nexport * from './tile-map'\r\n\r\nexport {\r\n s3,\r\n JSONL,\r\n tileMap\r\n}\r\n\r\nexport default {\r\n s3,\r\n JSONL,\r\n tileMap,\r\n utils: {\r\n ...jsMisc\r\n }\r\n}\r\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-console */\n\nexport interface IS3Config {\n region: string;\n bucket: string;\n accessKeyId: string;\n secretAccessKey: string;\n}\n\ntype S3Module = typeof import('@aws-sdk/client-s3');\nlet _mod: S3Module | null = null;\n\nasync function getModule(): Promise<S3Module> {\n if (!_mod) {\n try {\n _mod = await import('@aws-sdk/client-s3');\n } catch {\n throw new Error(\n '[beardos-toolbox] @aws-sdk/client-s3 is required to use the S3 helpers. ' +\n 'Install it: npm i @aws-sdk/client-s3'\n );\n }\n }\n return _mod;\n}\n\ntype S3ClientInstance = InstanceType<S3Module['S3Client']>;\nlet client: S3ClientInstance;\n\nexport const getClient = async ({ region, accessKeyId, secretAccessKey }: IS3Config): Promise<S3ClientInstance> => {\n if (!client) {\n const { S3Client } = await getModule();\n client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });\n }\n return client;\n};\n\nexport const putObject = async (config: IS3Config, data: Buffer | string, key: string, contentType?: string) => {\n try {\n const { PutObjectCommand } = await getModule();\n const cl = await getClient(config);\n const params: { Bucket: string; Key: string; Body: Buffer | string; ContentType?: string } = {\n Bucket: config.bucket,\n Key: key,\n Body: typeof data === 'string' ? Buffer.from(data, 'utf-8') : data,\n };\n if (contentType) params.ContentType = contentType;\n return await cl.send(new PutObjectCommand(params));\n } catch (e) {\n console.error('Could not upload object', { error: e });\n throw e;\n }\n};\n\nexport const getObject = async (config: IS3Config, key: string) => {\n const params = { Bucket: config.bucket, Key: key };\n try {\n const { GetObjectCommand } = await getModule();\n const cl = await getClient(config);\n return await cl.send(new GetObjectCommand(params));\n } catch (e) {\n console.error('Could not get object from s3', { error: e, params });\n throw e;\n }\n};\n\nexport const listObjects = async (config: IS3Config, prefix: string, Marker?: string) => {\n try {\n const { ListObjectsV2Command } = await getModule();\n const cl = await getClient(config);\n const params: import('@aws-sdk/client-s3').ListObjectsV2CommandInput = {\n Bucket: config.bucket,\n Prefix: prefix,\n ...(Marker ? { StartAfter: Marker } : {}),\n };\n const response = await cl.send(new ListObjectsV2Command(params));\n return { Objects: response.Contents ?? [], Marker: response.NextContinuationToken };\n } catch (e) {\n console.error('Could not list objects', { error: e });\n throw e;\n }\n};\n\nexport const deleteObject = async (config: IS3Config, Key: string) => {\n const params = { Bucket: config.bucket, Key };\n try {\n const { DeleteObjectCommand } = await getModule();\n const cl = await getClient(config);\n return await cl.send(new DeleteObjectCommand(params));\n } catch (e) {\n console.error('Could not delete object from s3', { error: e, params });\n throw e;\n }\n};\n", "import { EOL } from 'os'\r\n\r\n/**\r\n * made fairly specifically for arrays when dealing with larger qunatities of data that you may need to concat later\r\n */\r\n\r\nexport default {\r\n stringify: (data: any[]): string => {\r\n return data.map((d) => JSON.stringify(d)).join(EOL);\r\n },\r\n\r\n parse: (data: string): any[] => {\r\n return data.split(EOL).map((d, i) => {\r\n try{\r\n return JSON.parse(d);\r\n } catch (e: any) {\r\n console.error('Could not parse JSONL on line: ' + i, { error: e.message, line: i });\r\n }\r\n });\r\n },\r\n}\r\n \r\n", "const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\nconst chunkArray = (source: Array<any>, chunkSize: number = 10) => {\r\n const chunks = source.reduce((resultArray, item, index) => { \r\n const chunkIndex = Math.floor(index/chunkSize)\r\n \r\n if(!resultArray[chunkIndex]) {\r\n resultArray[chunkIndex] = []\r\n }\r\n \r\n resultArray[chunkIndex].push(item)\r\n \r\n return resultArray\r\n }, [])\r\n return chunks\r\n}\r\n\r\nconst settledSeparator = (result: Array<PromiseSettledResult<any>>) => {\r\n const settled = result.filter((r) => r.status === 'fulfilled')\r\n const rejected = result.filter((r) => r.status === 'rejected')\r\n return { settled, rejected, total: result.length }\r\n}\r\n \r\nconst timeFormat = (ms: number) => {\r\n if (ms < 1000) return `${ms} ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)} secs`;\r\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)} mins`;\r\n return `${(ms / 3600000).toFixed(2)} hrs`;\r\n}\r\n\r\nconst timeSinceString = (ms: number) => {\r\n return timeFormat(Date.now() - ms);\r\n}\r\n\r\nconst generateRandomString = (length = 8) => {\r\n return Math.random().toString(36).substring(2, 2 + length);\r\n}\r\n\r\n\r\nexport {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n\r\nexport default {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n", "// --- types ---\n\n/** A 2-D grid of tiles. `T` is the entity type stored per tile. */\nexport type TileMap<T = unknown> = {\n readonly width: number\n readonly height: number\n readonly size: number\n flags: Uint8Array\n entities: Map<number, T[]>\n}\n\n/**\n * A snapshot of a single tile's state.\n * `index` is the flat array position (`y * width + x`).\n */\nexport type TileInfo<T> = {\n readonly index: number\n readonly x: number\n readonly y: number\n flags: number\n entities: T[]\n}\n\n/** Shape used when collecting tiles or entities within a radius. */\nexport type RangeShape = 'square' | 'circle'\n\n/** Return `true` to pass, `false` to fail. Used by `validateTile` and `validateRange`. */\nexport type TileValidator<T> = (tile: TileInfo<T>) => boolean\n\n/**\n * Predefined single-bit flag constants.\n * Combine multiple flags with the bitwise OR operator:\n * ```ts\n * setFlag(map, x, y, TileFlags.BLOCKED | TileFlags.HAZARD)\n * ```\n * You can define additional custom flags as any unused power-of-two number\n * up to `0b10000000` (Uint8 supports 8 independent bits total).\n */\nexport const TileFlags = {\n NONE: 0b00000000,\n BLOCKED: 0b00000001,\n OCCUPIED: 0b00000010,\n VISIBLE: 0b00000100,\n EXPLORED: 0b00001000,\n WATER: 0b00010000,\n HAZARD: 0b00100000,\n} as const\n\n// --- internal helpers ---\n\nconst _idx = (width: number, x: number, y: number): number => y * width + x\n\nconst _inBounds = (width: number, height: number, x: number, y: number): boolean =>\n x >= 0 && x < width && y >= 0 && y < height\n\n// Packed dx/dy pairs for cardinal then diagonal neighbours\nconst _CARDINAL = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1])\nconst _ALL_ADJ = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1])\n\n// --- creation ---\n\n/**\n * Create a new tile map of the given dimensions.\n * All flags start at 0 and no entities are placed.\n * @param width Number of columns.\n * @param height Number of rows.\n * @returns A fresh `TileMap<T>`.\n * @example\n * type Unit = { id: string }\n * const map = createTileMap<Unit>(64, 64)\n */\nexport const createTileMap = <T>(width: number, height: number): TileMap<T> => ({\n width,\n height,\n size: width * height,\n flags: new Uint8Array(width * height),\n entities: new Map(),\n})\n\n// --- tile access ---\n\n/**\n * Convert grid coordinates to a flat array index.\n * Returns `-1` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileIndex = (map: TileMap<unknown>, x: number, y: number): number =>\n _inBounds(map.width, map.height, x, y) ? _idx(map.width, x, y) : -1\n\n/**\n * Return a `TileInfo` snapshot for the tile at `(x, y)`.\n * Returns `null` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileInfo = <T>(map: TileMap<T>, x: number, y: number): TileInfo<T> | null => {\n if (!_inBounds(map.width, map.height, x, y)) return null\n const index = _idx(map.width, x, y)\n return {\n index,\n x,\n y,\n flags: map.flags[index],\n entities: map.entities.get(index) ?? [],\n }\n}\n\n/**\n * Convert a flat array index back to `{ x, y }` grid coordinates.\n * @param map The tile map (used for its `width`).\n * @param index Flat tile index.\n */\nexport const indexToCoords = (map: TileMap<unknown>, index: number): { x: number; y: number } => ({\n x: index % map.width,\n y: (index / map.width) | 0,\n})\n\n// --- flag operations (bitwise, Uint8 supports 8 independent flags) ---\n\n/**\n * Set one or more flags on a tile using bitwise OR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) from `TileFlags` or a custom power-of-two constant.\n * @example\n * setFlag(map, 3, 5, TileFlags.BLOCKED)\n */\nexport const setFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] |= flag\n}\n\n/**\n * Clear one or more flags on a tile using bitwise AND NOT.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to clear.\n */\nexport const clearFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] &= ~flag\n}\n\n/**\n * Toggle one or more flags on a tile using bitwise XOR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to toggle.\n */\nexport const toggleFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] ^= flag\n}\n\n/**\n * Return `true` if **all** supplied flag bits are set on the tile.\n * Returns `false` for out-of-bounds coordinates.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to test.\n * @example\n * if (hasFlag(map, x, y, TileFlags.BLOCKED)) { ... }\n */\nexport const hasFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n return (map.flags[_idx(map.width, x, y)] & flag) !== 0\n}\n\n// --- entity operations ---\n\n/**\n * Add an entity to the tile at `(x, y)`.\n * Returns `false` when the coordinates are out of bounds (entity is not added).\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param entity The entity to place on the tile.\n */\nexport const addEntity = <T>(map: TileMap<T>, x: number, y: number, entity: T): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (bucket) bucket.push(entity)\n else map.entities.set(index, [entity])\n return true\n}\n\n/**\n * Remove the **first** entity on the tile at `(x, y)` for which `predicate` returns `true`.\n * Returns `false` when out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param predicate Selector \u2014 return `true` for the entity to remove.\n * @example\n * removeEntity(map, x, y, e => e.id === 'hero')\n */\nexport const removeEntity = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n predicate: (e: T) => boolean\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (!bucket) return false\n for (let i = 0; i < bucket.length; i++) {\n if (predicate(bucket[i])) {\n bucket.splice(i, 1)\n if (bucket.length === 0) map.entities.delete(index)\n return true\n }\n }\n return false\n}\n\n/**\n * Atomically move the **first** matching entity from one tile to another.\n * Returns `false` when either coordinate is out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param fromX Source column.\n * @param fromY Source row.\n * @param toX Destination column.\n * @param toY Destination row.\n * @param predicate Selector \u2014 return `true` for the entity to move.\n * @example\n * moveEntity(map, 2, 3, 2, 4, e => e.id === 'hero')\n */\nexport const moveEntity = <T>(\n map: TileMap<T>,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n predicate: (e: T) => boolean\n): boolean => {\n const { width, height } = map\n if (!_inBounds(width, height, fromX, fromY) || !_inBounds(width, height, toX, toY)) return false\n const srcIndex = _idx(width, fromX, fromY)\n const src = map.entities.get(srcIndex)\n if (!src) return false\n for (let i = 0; i < src.length; i++) {\n if (predicate(src[i])) {\n const entity = src[i]\n src.splice(i, 1)\n if (src.length === 0) map.entities.delete(srcIndex)\n const dstIndex = _idx(width, toX, toY)\n const dst = map.entities.get(dstIndex)\n if (dst) dst.push(entity)\n else map.entities.set(dstIndex, [entity])\n return true\n }\n }\n return false\n}\n\n/**\n * Return all entities on the tile at `(x, y)`.\n * Returns an empty array for out-of-bounds coordinates or tiles with no entities.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): T[] => {\n if (!_inBounds(map.width, map.height, x, y)) return []\n return map.entities.get(_idx(map.width, x, y)) ?? []\n}\n\n/**\n * Remove all entities from the tile at `(x, y)`.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const clearEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.entities.delete(_idx(map.width, x, y))\n}\n\n// --- adjacency ---\n\n/**\n * Return the flat indices of tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentIndices = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n includeDiagonals = false\n): number[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: number[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) result.push(_idx(width, nx, ny))\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentTiles = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n includeDiagonals = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: TileInfo<T>[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n return result\n}\n\n// --- range queries ---\n\n/**\n * Return the flat indices of all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Circle shape uses integer `dx\u00B2 + dy\u00B2 \u2264 range\u00B2` \u2014 no `Math.sqrt`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getIndicesInRange = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): number[] => {\n const { width, height } = map\n const r2 = range * range\n const result: number[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) result.push(_idx(width, nx, ny))\n }\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getTilesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const r2 = range * range\n const result: TileInfo<T>[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n }\n return result\n}\n\n/**\n * Collect and return every entity on every tile within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Tiles with no entities contribute nothing to the result.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include entities on the center tile itself (default `false`).\n * @example\n * const enemies = getEntitiesInRange(map, heroX, heroY, 3, 'circle')\n */\nexport const getEntitiesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): T[] => {\n const { width, height } = map\n const r2 = range * range\n const result: T[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const bucket = map.entities.get(_idx(width, nx, ny))\n if (bucket) for (let i = 0; i < bucket.length; i++) result.push(bucket[i])\n }\n }\n return result\n}\n\n// --- validation ---\n\n/**\n * Test whether the tile at `(x, y)` is in bounds and passes an optional validator.\n * When no `validator` is provided, returns `true` for any in-bounds coordinate.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param validator Optional predicate; receives a `TileInfo` snapshot.\n * @example\n * const passable = validateTile(map, x, y, t => !(t.flags & TileFlags.BLOCKED))\n */\nexport const validateTile = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n validator?: TileValidator<T>\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n if (!validator) return true\n const index = _idx(map.width, x, y)\n return validator({ index, x, y, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n}\n\n/**\n * Test whether **every** tile within `range` of `(x, y)` passes `validator`.\n * Short-circuits on the first failing tile. Out-of-bounds tiles are skipped entirely.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param validator Predicate; receives a `TileInfo` snapshot.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile in validation (default `false`).\n * @example\n * const areaClear = validateRange(map, x, y, 2, t => t.entities.length === 0)\n */\nexport const validateRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n validator: TileValidator<T>,\n shape: RangeShape = 'square',\n includeOrigin = false\n): boolean => {\n const { width, height } = map\n const r2 = range * range\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const index = _idx(width, nx, ny)\n if (!validator({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })) return false\n }\n }\n return true\n}\n\n// --- spatial / screen-space ---\n\n/**\n * Pixel dimensions of a single tile and an optional world-space origin offset.\n * Create once and reuse; it never mutates.\n *\n * - `tileWidth` / `tileHeight`: pixels per tile (e.g. 32 for a 32\u00D732 sprite sheet).\n * - `originX` / `originY`: world-pixel offset of tile (0, 0)'s top-left corner.\n * Use this to add margins or align the grid inside a larger world.\n *\n * Non-square tiles (e.g. 64\u00D732 isometric projections) are fully supported.\n */\nexport type SpatialConfig = {\n readonly tileWidth: number\n readonly tileHeight: number\n readonly originX: number\n readonly originY: number\n}\n\n/**\n * Fractional tile-grid position for an entity at an arbitrary world coordinate.\n * `tileX` / `tileY` are the integer grid cell; `fracX` / `fracY` are 0..1 offsets\n * within that cell \u2014 useful for smooth movement interpolation and collision checks.\n */\nexport type TilePosition = {\n tileX: number\n tileY: number\n fracX: number\n fracY: number\n}\n\n/**\n * Create a `SpatialConfig`.\n * @param tileWidth Pixels per tile column.\n * @param tileHeight Pixels per tile row.\n * @param originX World-pixel X of the grid's top-left corner (default `0`).\n * @param originY World-pixel Y of the grid's top-left corner (default `0`).\n * @example\n * const spatial = createSpatialConfig(32, 32)\n * const spatial = createSpatialConfig(64, 32, 128, 64) // offset grid\n */\nexport const createSpatialConfig = (\n tileWidth: number,\n tileHeight: number,\n originX = 0,\n originY = 0\n): SpatialConfig => ({ tileWidth, tileHeight, originX, originY })\n\n/**\n * Convert world-pixel coordinates to integer tile grid coordinates.\n * Fractions are floored, so the result is always the tile the point falls inside.\n * Returns `{ x: -1, y: -1 }` when the world position is before the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToTile = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: ((wx - spatial.originX) / spatial.tileWidth) | 0,\n y: ((wy - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **top-left corner**.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX,\n y: ty * spatial.tileHeight + spatial.originY,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **center**.\n * Useful for placing sprites, projectile origins, or distance calculations.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileCenterWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX + (spatial.tileWidth >> 1),\n y: ty * spatial.tileHeight + spatial.originY + (spatial.tileHeight >> 1),\n})\n\n/**\n * Convert screen-pixel coordinates to world-pixel coordinates using the camera offset.\n * The camera position is the world-space coordinate of the screen's top-left corner.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToWorld = (\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: sx + cameraX,\n y: sy + cameraY,\n})\n\n/**\n * Convert world-pixel coordinates to screen-pixel coordinates using the camera offset.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToScreen = (\n cameraX: number,\n cameraY: number,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: wx - cameraX,\n y: wy - cameraY,\n})\n\n/**\n * Convert screen-pixel coordinates directly to tile grid coordinates,\n * accounting for both the camera offset and the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToTile = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0,\n y: ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to screen-pixel coordinates (top-left of the tile),\n * accounting for the camera offset and grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToScreen = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX - cameraX,\n y: ty * spatial.tileHeight + spatial.originY - cameraY,\n})\n\n/**\n * Return the exact fractional tile-grid position for a world coordinate.\n * `tileX` / `tileY` are the integer grid cell the point is inside.\n * `fracX` / `fracY` are 0..1 fractions representing how far into the tile the point is \u2014\n * essential for smooth cross-tile movement, linear interpolation animations, and sub-tile collision.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * // Entity smoothly walking; determine which tile it's in and how far across\n * const pos = worldToTileExact(spatial, entity.x, entity.y)\n * // pos.fracX === 0.5 means entity is horizontally centred in its tile\n */\nexport const worldToTileExact = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TilePosition => {\n const fx = (wx - spatial.originX) / spatial.tileWidth\n const fy = (wy - spatial.originY) / spatial.tileHeight\n const tileX = fx | 0\n const tileY = fy | 0\n return { tileX, tileY, fracX: fx - tileX, fracY: fy - tileY }\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a world-pixel position falls on.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * const tile = getTileAtWorld(map, spatial, entity.x, entity.y)\n * if (tile && tile.flags & TileFlags.HAZARD) takeDamage(entity)\n */\nexport const getTileAtWorld = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TileInfo<T> | null => {\n const tx = ((wx - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((wy - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a screen-pixel position falls on,\n * accounting for the camera offset and grid origin.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n * @example\n * // Mouse click \u2192 tile lookup\n * const tile = getTileAtScreen(map, spatial, camera.x, camera.y, mouseX, mouseY)\n */\nexport const getTileAtScreen = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): TileInfo<T> | null => {\n const tx = ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n// --- default export ---\n\nexport default {\n TileFlags,\n createTileMap,\n getTileIndex,\n getTileInfo,\n indexToCoords,\n setFlag,\n clearFlag,\n toggleFlag,\n hasFlag,\n addEntity,\n removeEntity,\n moveEntity,\n getEntitiesAt,\n clearEntitiesAt,\n getAdjacentIndices,\n getAdjacentTiles,\n getIndicesInRange,\n getTilesInRange,\n getEntitiesInRange,\n validateTile,\n validateRange,\n createSpatialConfig,\n worldToTile,\n tileToWorld,\n tileCenterWorld,\n screenToWorld,\n worldToScreen,\n screenToTile,\n tileToScreen,\n worldToTileExact,\n getTileAtWorld,\n getTileAtScreen,\n}\n", "import * as s3 from './s3'\r\nexport * from './s3'\r\nimport JSONL from './jsonl'\r\nimport * as jsMisc from './misc-js-funcs'\r\nexport * from './misc-js-funcs'\r\nimport tileMap from './tile-map'\r\nexport * from './tile-map'\r\n\r\nexport {\r\n s3,\r\n JSONL,\r\n tileMap\r\n}\r\n\r\nexport default {\r\n s3,\r\n JSONL,\r\n tileMap,\r\n utils: {\r\n ...jsMisc\r\n }\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/s3.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { S3Client } from "@aws-sdk/client-s3";
|
|
2
1
|
export interface IS3Config {
|
|
3
2
|
region: string;
|
|
4
3
|
bucket: string;
|
|
5
4
|
accessKeyId: string;
|
|
6
5
|
secretAccessKey: string;
|
|
7
6
|
}
|
|
8
|
-
|
|
7
|
+
type S3Module = typeof import('@aws-sdk/client-s3');
|
|
8
|
+
type S3ClientInstance = InstanceType<S3Module['S3Client']>;
|
|
9
|
+
export declare const getClient: ({ region, accessKeyId, secretAccessKey }: IS3Config) => Promise<S3ClientInstance>;
|
|
9
10
|
export declare const putObject: (config: IS3Config, data: Buffer | string, key: string, contentType?: string) => Promise<import("@aws-sdk/client-s3").PutObjectCommandOutput>;
|
|
10
11
|
export declare const getObject: (config: IS3Config, key: string) => Promise<import("@aws-sdk/client-s3").GetObjectCommandOutput>;
|
|
11
12
|
export declare const listObjects: (config: IS3Config, prefix: string, Marker?: string) => Promise<{
|
|
@@ -13,3 +14,4 @@ export declare const listObjects: (config: IS3Config, prefix: string, Marker?: s
|
|
|
13
14
|
Marker: string | undefined;
|
|
14
15
|
}>;
|
|
15
16
|
export declare const deleteObject: (config: IS3Config, Key: string) => Promise<import("@aws-sdk/client-s3").DeleteObjectCommandOutput>;
|
|
17
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beardos-toolbox",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Handy scripts and libs that I don't want to write again but don't need their own individual repos",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@aws-sdk/client-s3": "^3.0.0",
|
|
35
|
-
"@types/node": "^22.
|
|
35
|
+
"@types/node": "^22.19.18",
|
|
36
36
|
"esbuild": "^0.25.0",
|
|
37
37
|
"tsx": "^4.21.0",
|
|
38
38
|
"typescript": "^5.0.0"
|