| import type { autocomplete } from "./generics.ts"; | ||
| export declare const isomorphic: { | ||
| fileName: () => string; | ||
| env: Record<autocomplete<"ARK_DEBUG">, string | undefined>; | ||
| }; |
| // based on the util of the same name in @ark/fs | ||
| // isolated here for use with registry | ||
| /** get a CJS/ESM compatible string representing the current file */ | ||
| const fileName = () => { | ||
| try { | ||
| const error = new Error(); | ||
| const stackLine = error.stack?.split("\n")[2]?.trim() || ""; // [1]=this func, [2]=caller | ||
| const filePath = stackLine.match(/\(?(.+?)(?::\d+:\d+)?\)?$/)?.[1] || "unknown"; | ||
| return filePath.replace(/^file:\/\//, ""); | ||
| } | ||
| catch { | ||
| return "unknown"; | ||
| } | ||
| }; | ||
| const env = globalThis.process?.env ?? {}; | ||
| export const isomorphic = { | ||
| fileName, | ||
| env | ||
| }; |
+1
-1
@@ -1,2 +0,2 @@ | ||
| Copyright 2024 ArkType | ||
| Copyright 2025 ArkType | ||
@@ -3,0 +3,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
+11
-0
@@ -5,2 +5,13 @@ import type { GuardablePredicate } from "./functions.ts"; | ||
| import type { parseNonNegativeInteger } from "./numbers.ts"; | ||
| type DuplicateData<val = unknown> = { | ||
| element: val; | ||
| indices: number[]; | ||
| }; | ||
| /** | ||
| * Extracts duplicated elements and their indices from an array, returning them. | ||
| * | ||
| * Note that given `a === b && b === c`, then `c === a` must be `true` for this to give accurate results. | ||
| * | ||
| * @param arr The array to extract duplicate elements from. | ||
| */ export declare const getDuplicatesOf: <const arr extends array>(arr: arr, opts?: ComparisonOptions<arr[number]>) => DuplicateData<arr[number]>[]; | ||
| export type pathToString<segments extends string[], delimiter extends string = "/"> = segments extends [] ? "/" : join<segments, delimiter>; | ||
@@ -7,0 +18,0 @@ export declare const join: <segments extends array<string>, delimiter extends string>(segments: segments, delimiter: delimiter) => join<segments, delimiter>; |
+40
-0
@@ -0,1 +1,41 @@ | ||
| /** | ||
| * Extracts duplicated elements and their indices from an array, returning them. | ||
| * | ||
| * Note that given `a === b && b === c`, then `c === a` must be `true` for this to give accurate results. | ||
| * | ||
| * @param arr The array to extract duplicate elements from. | ||
| */ export const getDuplicatesOf = (arr, opts) => { | ||
| const isEqual = opts?.isEqual ?? ((l, r) => l === r); | ||
| const elementFirstSeenIndx = new Map(); | ||
| const duplicates = []; | ||
| for (const [indx, element] of arr.entries()) { | ||
| const duplicatesIndx = duplicates.findIndex(duplicate => isEqual(duplicate.element, element)); | ||
| if (duplicatesIndx !== -1) { | ||
| // This is at least the third occurence of an item equal to `element`, | ||
| // so add this index to the list of indices where the element is duplicated. | ||
| duplicates[duplicatesIndx].indices.push(indx); | ||
| continue; | ||
| } | ||
| // At this point, we know this is either the first | ||
| // or second occurence of an item equal to `element`... | ||
| let found = false; | ||
| for (const [existingElement, firstSeenIndx] of elementFirstSeenIndx) { | ||
| if (isEqual(element, existingElement)) { | ||
| // This is the second occurence of an item equal to `element`, | ||
| // so store it as a duplicate. | ||
| found = true; | ||
| duplicates.push({ | ||
| element: existingElement, | ||
| indices: [firstSeenIndx, indx] | ||
| }); | ||
| } | ||
| } | ||
| if (!found) { | ||
| // We haven't seen this element before, | ||
| // so just store the index it was first seen | ||
| elementFirstSeenIndx.set(element, indx); | ||
| } | ||
| } | ||
| return duplicates; | ||
| }; | ||
| export const join = (segments, delimiter) => segments.join(delimiter); | ||
@@ -2,0 +42,0 @@ export const getPath = (root, path) => { |
+1
-0
@@ -11,2 +11,3 @@ export * from "./arrays.ts"; | ||
| export * from "./intersections.ts"; | ||
| export * from "./isomorphic.ts"; | ||
| export * from "./keys.ts"; | ||
@@ -13,0 +14,0 @@ export * from "./lazily.ts"; |
+1
-0
@@ -11,2 +11,3 @@ export * from "./arrays.js"; | ||
| export * from "./intersections.js"; | ||
| export * from "./isomorphic.js"; | ||
| export * from "./keys.js"; | ||
@@ -13,0 +14,0 @@ export * from "./lazily.js"; |
@@ -1,2 +0,2 @@ | ||
| export declare const arkUtilVersion = "0.45.6"; | ||
| export declare const arkUtilVersion = "0.45.7"; | ||
| export declare const initialRegistryContents: { | ||
@@ -3,0 +3,0 @@ version: string; |
+3
-3
| import { domainOf } from "./domain.js"; | ||
| import { throwInternalError } from "./errors.js"; | ||
| import { tryCatch } from "./functions.js"; | ||
| import { isomorphic } from "./isomorphic.js"; | ||
| import { FileConstructor, objectKindOf } from "./objectKinds.js"; | ||
@@ -9,6 +9,6 @@ // Eventually we can just import from package.json in the source itself | ||
| // For now, we assert this matches the package.json version via a unit test. | ||
| export const arkUtilVersion = "0.45.6"; | ||
| export const arkUtilVersion = "0.45.7"; | ||
| export const initialRegistryContents = { | ||
| version: arkUtilVersion, | ||
| filename: tryCatch(() => import.meta.filename ?? undefined, () => globalThis.__filename ?? "unknown"), | ||
| filename: isomorphic.fileName(), | ||
| FileConstructor | ||
@@ -15,0 +15,0 @@ }; |
+1
-1
| { | ||
| "name": "@ark/util", | ||
| "version": "0.45.6", | ||
| "version": "0.45.7", | ||
| "license": "MIT", | ||
@@ -5,0 +5,0 @@ "author": { |
106564
2.91%55
3.77%2342
3.4%