Skip to content

Commit

Permalink
Merge pull request #5 from urbit/hm/combining-libs
Browse files Browse the repository at this point in the history
types: adding ud, ux, p, and q
  • Loading branch information
arthyn authored Apr 13, 2023
2 parents b451907 + 81b6fea commit d3b8cf2
Show file tree
Hide file tree
Showing 21 changed files with 17,799 additions and 7,921 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node: ['10.x', '12.x', '14.x']
node: ['16.x', '18.x']
os: [ubuntu-latest, windows-latest, macOS-latest]

steps:
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16
23,549 changes: 16,050 additions & 7,499 deletions package-lock.json

Large diffs are not rendered by default.

53 changes: 27 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
{
"version": "0.6.0",
"license": "MIT",
"name": "@urbit/aura",
"author": "Liam Fitzgerald",
"module": "dist/aura.esm.js",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
"dist",
"src"
"dist"
],
"engines": {
"node": ">=10"
"node": ">=16",
"npm": ">=8"
},
"repository": {
"type": "git",
"url": "https://github.com/urbit/aura-js"
},
"scripts": {
"start": "tsdx watch",
"build": "tsdx build",
"test": "tsdx test",
"lint": "tsdx lint",
"prepare": "tsdx build",
"start": "dts watch",
"build": "dts build",
"test": "dts test",
"lint": "dts lint",
"prepare": "dts build",
"size": "size-limit",
"analyze": "size-limit --why"
},
"peerDependencies": {
"big-integer": "^1.6.51"
},
"devDependencies": {
"@size-limit/preset-small-lib": "^8.2.4",
"@tsconfig/recommended": "^1.0.2",
"dts-cli": "^2.0.0",
"husky": "^7.0.4",
"jsverify": "^0.8.4",
"tslib": "^2.5.0",
"typescript": "^5.0.4"
},
"jest": {
"verbose": true
},
"peerDependencies": {},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
"pre-commit": "dts lint"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
"trailingComma": "es5",
"endOfLine": "auto"
},
"name": "@urbit/aura",
"author": "Liam Fitzgerald",
"module": "dist/aura.esm.js",
"size-limit": [
{
"path": "dist/aura.cjs.production.min.js",
Expand All @@ -50,16 +62,5 @@
"path": "dist/aura.esm.js",
"limit": "10 KB"
}
],
"devDependencies": {
"@size-limit/preset-small-lib": "^7.0.8",
"husky": "^7.0.4",
"size-limit": "^7.0.8",
"tsdx": "^0.14.1",
"tslib": "^2.4.0",
"typescript": "^4.6.4"
},
"dependencies": {
"big-integer": "^1.6.51"
}
]
}
238 changes: 238 additions & 0 deletions src/da.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import bigInt, { BigInteger } from 'big-integer';

interface Dat {
pos: boolean;
year: BigInteger;
month: BigInteger;
time: Tarp;
}

interface Tarp {
day: BigInteger;
hour: BigInteger;
minute: BigInteger;
second: BigInteger;
ms: BigInteger[];
}

const DA_UNIX_EPOCH = bigInt('170141184475152167957503069145530368000'); // `@ud` ~1970.1.1

const DA_SECOND = bigInt('18446744073709551616'); // `@ud` ~s1

const EPOCH = bigInt('292277024400');
const zero = bigInt.zero;

function isLeapYear(year: BigInteger) {
return year.mod(4).eq(zero) && (year.mod(100).neq(0) || year.mod(400).eq(0));
}
const MOH_YO = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const MOY_YO = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const DAY_YO = bigInt(86400);
const HOR_YO = bigInt(3600);
const MIT_YO = bigInt(60);
const ERA_YO = bigInt(146097);
const CET_YO = bigInt(36524);

export function year(det: Dat) {
const yer = det.pos
? EPOCH.add(bigInt(det.year))
: EPOCH.subtract(bigInt(det.year).prev());
const day = (() => {
let cah = isLeapYear(yer) ? MOY_YO : MOH_YO;
let d = det.time.day.prev();
let m = det.month.prev();
while (m.neq(0)) {
const [first, ...rest] = cah;
d = d.add(bigInt(first));
m = m.prev();
cah = rest;
}
let loop: boolean = true;
let y = yer;
while (loop == true) {
if (y.mod(4).neq(zero)) {
y = y.minus(1);
d = d.add(isLeapYear(y) ? 366 : 365);
} else if (y.mod(100).neq(zero)) {
y = y.minus(bigInt(4));
d = d.add(isLeapYear(y) ? 1461 : 1460);
} else if (y.mod(400).neq(zero)) {
y = y.minus(bigInt(100));
d = d.add(isLeapYear(y) ? 36525 : 36524);
} else {
let eras = y.divide(bigInt(400));
d = d.add(eras.multiply(bigInt(4).multiply(bigInt(36524)).next()));
loop = false;
}
}
return d;
})();

let sec = bigInt(det.time.second)
.add(DAY_YO.multiply(day))
.add(HOR_YO.multiply(bigInt(det.time.hour)))
.add(MIT_YO.multiply(bigInt(det.time.minute)));

let ms = det.time.ms;
let fac = bigInt.zero;
let muc = 3;
while (ms.length !== 0) {
const [first, ...rest] = ms;
fac = fac.add(first.shiftLeft(bigInt(16 * muc)));
ms = rest;
muc -= 1;
}

return fac.or(sec.shiftLeft(64));
}

/**
* Given a string formatted as a @da, returns a bigint representing the urbit date.
*
* @return {string} x The formatted @da
* @return {BigInteger} x The urbit date as bigint
*/
export function parseDa(x: string): BigInteger {
const [date, time, ms] = x.split('..');
const [yer, month, day] = date.slice(1).split('.');
const [hour, minute, sec] = time.split('.');
const millis = ms.split('.').map((m) => bigInt(m, 16));

return year({
pos: true,
year: bigInt(yer, 10),
month: bigInt(month, 10),
time: {
day: bigInt(day, 10),
hour: bigInt(hour, 10),
minute: bigInt(minute, 10),
second: bigInt(sec, 10),
ms: millis,
},
});
}

function yell(x: BigInteger): Tarp {
let sec = x.shiftRight(64);
const milliMask = bigInt('ffffffffffffffff', 16);
const millis = milliMask.and(x);
const ms = millis
.toString(16)
.match(/.{1,4}/g)!
.filter((x) => x !== '0000')
.map((x) => bigInt(x, 16));
let day = sec.divide(DAY_YO);
sec = sec.mod(DAY_YO);
let hor = sec.divide(HOR_YO);
sec = sec.mod(HOR_YO);
let mit = sec.divide(MIT_YO);
sec = sec.mod(MIT_YO);

return {
ms,
day,
minute: mit,
hour: hor,
second: sec,
};
}

function yall(day: BigInteger): [BigInteger, BigInteger, BigInteger] {
let era = zero;
let cet = zero;
let lep = false;
era = day.divide(ERA_YO);
day = day.mod(ERA_YO);
if (day.lt(CET_YO.next())) {
lep = true;
} else {
lep = false;
cet = bigInt(1);
day = day.minus(CET_YO.next());
cet = cet.add(day.divide(CET_YO));
day = day.mod(CET_YO);
}
let yer = era.multiply(400).add(cet.multiply(100));
let loop = true;
while (loop == true) {
let dis = lep ? 366 : 365;
if (!day.lt(dis)) {
yer = yer.next();
day = day.minus(dis);
lep = yer.mod(4).eq(0);
} else {
loop = false;
let inner = true;
let mot = zero;
while (inner) {
let cah = lep ? MOY_YO : MOH_YO;
let zis = cah[mot.toJSNumber()];
if (day.lt(zis)) {
return [yer, mot.next(), day.next()];
}
mot = mot.next();
day = day.minus(zis);
}
}
}
return [zero, zero, zero];
}

function yore(x: BigInteger): Dat {
const time = yell(x);
const [y, month, d] = yall(time.day);
time.day = d;
const pos = y.gt(EPOCH);
const year = pos ? y.minus(EPOCH) : EPOCH.minus(y).next();

return {
pos,
year,
month,
time,
};
}

/**
* Given a bigint representing an urbit date, returns a string formatted as a proper @da.
*
* @param {BigInteger} x The urbit date as bigint
* @return {string} The formatted @da
*/
export function formatDa(x: BigInteger | string) {
if (typeof x === 'string') {
x = bigInt(x);
}
const { year, month, time } = yore(x);

return `~${year}.${month}.${time.day}..${time.hour}.${time.minute}.${
time.second
}..${time.ms.map((x) => x.toString(16).padStart(4, '0')).join('.')}`;
}

/**
* Given a bigint representing an urbit date, returns a unix timestamp.
*
* @param {BigInteger} da The urbit date
* @return {number} The unix timestamp
*/
export function daToUnix(da: BigInteger): number {
// ported from +time:enjs:format in hoon.hoon
const offset = DA_SECOND.divide(bigInt(2000));
const epochAdjusted = offset.add(da.subtract(DA_UNIX_EPOCH));

return Math.round(
epochAdjusted.multiply(bigInt(1000)).divide(DA_SECOND).toJSNumber()
);
}

/**
* Given a unix timestamp, returns a bigint representing an urbit date
*
* @param {number} unix The unix timestamp
* @return {BigInteger} The urbit date
*/
export function unixToDa(unix: number): BigInteger {
const timeSinceEpoch = bigInt(unix).multiply(DA_SECOND).divide(bigInt(1000));
return DA_UNIX_EPOCH.add(timeSinceEpoch);
}
Loading

0 comments on commit d3b8cf2

Please sign in to comment.