mirror of
https://github.com/urbit/shrub.git
synced 2024-12-02 21:34:04 +03:00
Merge branch 'master' into next/groups
This commit is contained in:
commit
4ee680807f
@ -168,6 +168,11 @@
|
||||
%+ turn ~(tap by charges)
|
||||
|= [=desk =charge]
|
||||
[desk (get-light-charge charge)]
|
||||
::
|
||||
[%x %charges @ %version ~]
|
||||
?~ charge=(~(get by charges) i.t.t.path)
|
||||
[~ ~]
|
||||
``noun+!>(version.docket.u.charge)
|
||||
==
|
||||
::
|
||||
++ on-agent
|
||||
|
@ -4,4 +4,5 @@ bin/
|
||||
.vscode/
|
||||
.husky/
|
||||
*.config.js
|
||||
*.config.ts
|
||||
*.config.ts
|
||||
package.json
|
47
pkg/grid/CONTRIBUTING.md
Normal file
47
pkg/grid/CONTRIBUTING.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Contributing to Landscape
|
||||
|
||||
Thank you for your interest in contributing to the Urbit ecosystem.
|
||||
|
||||
Landscape is entirely open to contributions from the community. We mainly organize through our [project board], [issues], and [weekly call].
|
||||
|
||||
For now our code is stored in the main [urbit repo]. If you would like to contribute feel free to open up a PR there.
|
||||
|
||||
## Git Conventions
|
||||
|
||||
For Landscape we follow the same conventions as the main repo which can be found in it's [contributing doc]. This can be summarized as the following:
|
||||
|
||||
Commits should try to be atomic and focused on one feature at a time. Work-in-progress commits should be rebased and combined into one so that the commit history stays clean.
|
||||
|
||||
Commits should follow this format:
|
||||
|
||||
> component: short description
|
||||
>
|
||||
> long description
|
||||
|
||||
Where `component` is the closest most relevant area of the code base written as concisely as possible. The short description that accompanies should be a super concise summary of the changes. The total length of the commit message should strive to be 50 characters or less. The long description is optional, but should be used if further explanation is necessary.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
A pull request (PR) should have a title similar in structure to our commit messages where it has a short identifier component followed by a very concise summary of the PR's intent. All PRs should have a description further laying out what it accomplishes. If the PR addresses certain Github issues, those should be referenced in the body of the description so they get linked.
|
||||
|
||||
PRs to this repo should currently tag (or request review) from one of the following contributors:
|
||||
|
||||
- [Liam - @liam-fitzgerald](https://github.com/liam-fitzgerald)
|
||||
- [Hunter - @arthyn](https://github.com/arthyn)
|
||||
- [James - @nerveharp](https://github.com/nerveharp)
|
||||
|
||||
If design or visual changes are made, please provide screenshots and also tag (or request a review) from one of the following contributors:
|
||||
|
||||
- [Éd - @urcades](https://github.com/urcades)
|
||||
- [Gavin - @g-a-v-i-n](https://github.com/g-a-v-i-n)
|
||||
|
||||
## Further Information
|
||||
|
||||
If you haven't yet, check out the main [contributing doc] at the base of the repo for information on how to get started developing on Urbit. Also you can find a host of resources on [developers.urbit.org], including ways to earn address space by contributing.
|
||||
|
||||
[project board]: https://github.com/orgs/urbit/projects/17
|
||||
[issues]: https://github.com/urbit/landscape/issues
|
||||
[weekly call]: https://github.com/urbit/landscape/issues/792
|
||||
[urbit repo]: https://github.com/urbit/urbit
|
||||
[contributing doc]: ../../CONTRIBUTING.md
|
||||
[developers.urbit.org]: https://developers.urbit.org/
|
43
pkg/grid/README.md
Normal file
43
pkg/grid/README.md
Normal file
@ -0,0 +1,43 @@
|
||||
# Landscape
|
||||
|
||||
Landscape provides the primary launching interface for Tlon's suite of userspace applications. This directory contains the front-end web application to power said interface.
|
||||
|
||||
Landscape is built primarily using [React], [Typescript], and [Tailwind CSS]. [Vite] ensures that all code and assets are loaded appropriately, bundles the application for distribution and provides a functional dev environment.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started using Landscape first you need to run, `npm i && npm run bootstrap` at the top level of the greater urbit repo. This will install your npm dependencies and correctly link the current implementation of the packages at `pkg/npm/*` to your dependencies.
|
||||
|
||||
If you intend to edit those packages will developing on Landscape, you should also have `npm run watch-libs` running to build and re-link them after every change.
|
||||
|
||||
Once that's done, you can then run `npm run mock` if you'd like to get started immediately. This will use hard-coded mock data to power the interface so you can work on the interface without being connected to a ship.
|
||||
|
||||
To develop against a working ship, you first need to add a `.env.local` file to the root of this directory. This file will not be committed. Adding `VITE_SHIP_URL={URL}` where **{URL}** is the URL of the ship you would like to point to, will allow you to run `npm run dev`. This will proxy all requests to the ship except for those powering the interface, allowing you to see live data.
|
||||
|
||||
Regardless of what you run to develop, Vite will hot-reload code changes as you work so you don't have to constantly refresh.
|
||||
|
||||
## Deploying
|
||||
|
||||
To deploy, run `npm run build` which will bundle all the code and assets into the `dist/` folder. This can then be made into a glob by doing the following:
|
||||
|
||||
1. Create or launch an urbit using the -F flag
|
||||
2. On that urbit, if you don't already have a desk to run from, run `|merge %work our %base` to create a new desk and mount it with `|mount %work`.
|
||||
3. Now the `%work` desk is accessible through the host OS's filesystem as a directory of that urbit's pier ie `~/zod/work`.
|
||||
4. From the directory of grid you can run `rsync -avL --delete dist/ ~/zod/work/grid` where `~/zod` is your fake urbit's pier.
|
||||
5. Once completed you can then run `|commit %work` on your urbit and you should see your files logged back out from the dojo.
|
||||
6. Now run `=dir /=garden` to switch to the garden desk directory
|
||||
7. You can now run `-make-glob %work /grid` which will take the grid folder where you just added files and create a glob which can be thought of as a sort of bundle. It will be output to `~/zod/.urb/put`.
|
||||
8. If you navigate to `~/zod/.urb/put` you should see a file that looks like this `glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob`. The characters between `glob-` and `.glob` are a hash of the glob's contents.
|
||||
9. If you're working at Tlon, you can upload this to our Google storage using `gsutil cp glob-*.* gs://bootstrap.urbit.org`. Otherwise any publicly available HTTP endpoint that can serve files should be sufficient for distributing the glob.
|
||||
10. Once you've uploaded the glob, you should then update the corresponding entry in the docket file that represents Landscape which currently resides at `pkg/garden/desk.docket-0`. Both the full URL and the hash should be updated to match the glob we just created, on the line that looks like this:
|
||||
|
||||
```hoon
|
||||
glob-http+['https://bootstrap.urbit.org/glob-0v5.fdf99.nph65.qecq3.ncpjn.q13mb.glob' 0v5.fdf99.nph65.qecq3.ncpjn.q13mb]
|
||||
```
|
||||
|
||||
11. This can now be safely committed and deployed.
|
||||
|
||||
[react]: https://reactjs.org/
|
||||
[typescript]: https://www.typescriptlang.org/
|
||||
[tailwind css]: https://tailwindcss.com/
|
||||
[vite]: https://vitejs.dev/
|
27529
pkg/grid/package-lock.json
generated
27529
pkg/grid/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "landscape",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"mock": "vite --mode mock",
|
||||
@ -21,8 +22,8 @@
|
||||
"@radix-ui/react-toggle": "^0.0.10",
|
||||
"@tlon/sigil-js": "^1.4.4",
|
||||
"@types/lodash": "^4.14.172",
|
||||
"@urbit/api": "^1.4.0",
|
||||
"@urbit/http-api": "^1.3.1",
|
||||
"@urbit/api": "^2.1.0",
|
||||
"@urbit/http-api": "^2.1.0",
|
||||
"big-integer": "^1.6.48",
|
||||
"classnames": "^2.3.1",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { chadIsRunning, Treaty } from '@urbit/api';
|
||||
import { chadIsRunning, Treaty, Vat } from '@urbit/api';
|
||||
import clipboardCopy from 'clipboard-copy';
|
||||
import React, { FC, useCallback, useState } from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Vat } from '@urbit/api/hood';
|
||||
import { Button, PillButton } from './Button';
|
||||
import { Dialog, DialogClose, DialogContent, DialogTrigger } from './Dialog';
|
||||
import { DocketHeader } from './DocketHeader';
|
||||
@ -137,19 +136,19 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
|
||||
</div>
|
||||
</DocketHeader>
|
||||
<div className="space-y-6">
|
||||
{vat ? (
|
||||
<>
|
||||
<hr className="-mx-5 sm:-mx-8 border-gray-50" />
|
||||
<VatMeta vat={vat} />
|
||||
</>
|
||||
) : null}
|
||||
{!treaty ? null : (
|
||||
<>
|
||||
<hr className="-mx-5 sm:-mx-8 border-gray-50" />
|
||||
<TreatyMeta treaty={treaty} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{vat ? (
|
||||
<>
|
||||
<hr className="-mx-5 sm:-mx-8 border-gray-50" />
|
||||
<VatMeta vat={vat} />
|
||||
</>
|
||||
) : null}
|
||||
{!treaty ? null : (
|
||||
<>
|
||||
<hr className="-mx-5 sm:-mx-8 border-gray-50" />
|
||||
<TreatyMeta treaty={treaty} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Docket } from '@urbit/api/docket';
|
||||
import { Docket } from '@urbit/api';
|
||||
import cn from 'classnames';
|
||||
import { useTileColor } from '../tiles/useTileColor';
|
||||
|
||||
|
@ -7,7 +7,13 @@ type ShipNameProps = {
|
||||
|
||||
export const ShipName = ({ name, ...props }: ShipNameProps) => {
|
||||
const separator = /([_^-])/;
|
||||
const parts = cite(name).replace('~', '').split(separator);
|
||||
const citedName = cite(name);
|
||||
|
||||
if (!citedName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const parts = citedName.replace('~', '').split(separator);
|
||||
const first = parts.shift();
|
||||
|
||||
return (
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Vat } from '@urbit/api/hood';
|
||||
import { Vat } from '@urbit/api';
|
||||
|
||||
import { Attribute } from './Attribute';
|
||||
|
||||
|
@ -3,7 +3,7 @@ import classNames from 'classnames';
|
||||
import clipboardCopy from 'clipboard-copy';
|
||||
import React, { HTMLAttributes, useCallback, useState } from 'react';
|
||||
import { Link, Route, useHistory } from 'react-router-dom';
|
||||
import { Vat } from '@urbit/api/hood';
|
||||
import { Vat } from '@urbit/api';
|
||||
import { Adjust } from '../components/icons/Adjust';
|
||||
import { useVat } from '../state/kiln';
|
||||
import { disableDefault, handleDropdownLink } from '../state/util';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { pick, pickBy, partition } from 'lodash';
|
||||
import React, { useCallback } from 'react';
|
||||
import { kilnBump } from '@urbit/api/hood';
|
||||
import { kilnBump } from '@urbit/api';
|
||||
import { AppList } from '../../components/AppList';
|
||||
import { Button } from '../../components/Button';
|
||||
import { Dialog, DialogClose, DialogContent, DialogTrigger } from '../../components/Dialog';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { setMentions } from '@urbit/api/dist';
|
||||
import { setMentions } from '@urbit/api';
|
||||
import React from 'react';
|
||||
import { Setting } from '../../components/Setting';
|
||||
import { pokeOptimisticallyN } from '../../state/base';
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import {
|
||||
BigIntOrderedMap,
|
||||
makePatDa,
|
||||
decToUd,
|
||||
unixToDa,
|
||||
@ -13,7 +14,6 @@ import {
|
||||
NotificationGraphConfig,
|
||||
archiveAll
|
||||
} from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
/* eslint-disable-next-line camelcase */
|
||||
import { unstable_batchedUpdates } from 'react-dom';
|
||||
import produce from 'immer';
|
||||
|
@ -1,5 +1,13 @@
|
||||
import { getVats, Vats, scryLag, getBlockers, Vat, kilnInstall } from '@urbit/api';
|
||||
import { kilnPause, kilnResume } from '@urbit/api/hood';
|
||||
import {
|
||||
getVats,
|
||||
Vats,
|
||||
scryLag,
|
||||
getBlockers,
|
||||
Vat,
|
||||
kilnInstall,
|
||||
kilnPause,
|
||||
kilnResume
|
||||
} from '@urbit/api';
|
||||
import create from 'zustand';
|
||||
import produce from 'immer';
|
||||
import { useCallback } from 'react';
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
putEntry as doPutEntry,
|
||||
getDeskSettings,
|
||||
DeskData
|
||||
} from '@urbit/api/settings';
|
||||
} from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
BaseState,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Docket, DocketHref, Treaty } from '@urbit/api/docket';
|
||||
import { Docket, DocketHref, Treaty } from '@urbit/api';
|
||||
import { hsla, parseToHsla } from 'color2k';
|
||||
import _ from 'lodash';
|
||||
|
||||
|
@ -73,7 +73,7 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
},
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react)\/).*/
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react|@urbit\/api)\/).*/
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
|
@ -30,7 +30,7 @@ module.exports = {
|
||||
]
|
||||
}
|
||||
},
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react)\/).*/
|
||||
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react|@urbit\/api)\/).*/
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
|
96236
pkg/interface/package-lock.json
generated
96236
pkg/interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -15,8 +15,8 @@
|
||||
"@tlon/indigo-light": "^1.0.7",
|
||||
"@tlon/indigo-react": "^1.2.27",
|
||||
"@tlon/sigil-js": "^1.4.3",
|
||||
"@urbit/api": "^1.4.0",
|
||||
"@urbit/http-api": "^1.2.1",
|
||||
"@urbit/api": "^2.1.0",
|
||||
"@urbit/http-api": "^2.1.0",
|
||||
"any-ascii": "^0.1.7",
|
||||
"aws-sdk": "^2.830.0",
|
||||
"big-integer": "^1.6.48",
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Content, GraphNode, unixToDa } from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import { BigIntOrderedMap, Content, GraphNode, unixToDa } from '@urbit/api';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
|
||||
export const makeComment = (
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { deSig, Path, PatpNoSig } from '@urbit/api';
|
||||
import { Group, Resource, roleTags, RoleTags } from '@urbit/api/groups';
|
||||
import { deSig, Path, PatpNoSig, Group, Resource, roleTags, RoleTags } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
|
||||
export function roleForShip(
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Content, GraphNode, Post, TextContent } from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import { BigIntOrderedMap, Content, GraphNode, Post, TextContent } from '@urbit/api';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import { buntPost } from '~/logic/lib/post';
|
||||
import { unixToDa } from '~/logic/lib/util';
|
||||
|
@ -1,9 +1,4 @@
|
||||
import { GraphNode } from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import BigIntArrayOrderedMap, {
|
||||
arrToString,
|
||||
stringToArr
|
||||
} from '@urbit/api/lib/BigIntArrayOrderedMap';
|
||||
import { arrToString, stringToArr, BigIntOrderedMap, BigIntArrayOrderedMap, GraphNode } from '@urbit/api';
|
||||
import bigInt, { BigInteger } from 'big-integer';
|
||||
import produce from 'immer';
|
||||
import _ from 'lodash';
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { Enc } from '@urbit/api';
|
||||
import {
|
||||
Enc,
|
||||
Group,
|
||||
|
||||
GroupPolicy, GroupUpdate,
|
||||
|
||||
InvitePolicy, InvitePolicyDiff, OpenPolicy, OpenPolicyDiff, Tags
|
||||
} from '@urbit/api/groups';
|
||||
} from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { resourceAsPath } from '../lib/util';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
BigIntOrderedMap,
|
||||
HarkPlace,
|
||||
Timebox,
|
||||
HarkStats,
|
||||
harkBinToId,
|
||||
makePatDa
|
||||
} from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import _ from 'lodash';
|
||||
import { compose } from 'lodash/fp';
|
||||
import { BaseState } from '../state/base';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { InviteUpdate } from '@urbit/api/invite';
|
||||
import { InviteUpdate } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { BaseState } from '../state/base';
|
||||
import { InviteState as State } from '../state/invite';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MetadataUpdate, Associations, ResourceAssociations } from '@urbit/api/metadata';
|
||||
import { MetadataUpdate, Associations, ResourceAssociations } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { Cage } from '~/types/cage';
|
||||
import { BaseState } from '../state/base';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { SettingsUpdate } from '@urbit/api/settings';
|
||||
import { SettingsUpdate } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { SettingsState as State } from '~/logic/state/settings';
|
||||
import { BaseState } from '../state/base';
|
||||
|
@ -1,12 +1,12 @@
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import { patp2dec } from 'urbit-ob';
|
||||
import shallow from 'zustand/shallow';
|
||||
|
||||
import { Association, deSig, GraphNode, Graphs, FlatGraphs, resourceFromPath, ThreadGraphs, getGraph, getShallowChildren, setScreen } from '@urbit/api';
|
||||
import {
|
||||
Association, BigIntOrderedMap, deSig, GraphNode, Graphs, FlatGraphs, resourceFromPath, ThreadGraphs, getGraph, getShallowChildren, setScreen,
|
||||
addDmMessage, addPost, Content, getDeepOlderThan, getFirstborn, getNewest, getNode, getOlderSiblings, getYoungerSiblings, markPending, Post, addNode, GraphNodePoke
|
||||
} from '@urbit/api';
|
||||
import { useCallback } from 'react';
|
||||
import { createState, createSubscription, reduceStateN, pokeOptimisticallyN } from './base';
|
||||
import airlock from '~/logic/api';
|
||||
import { addDmMessage, addPost, Content, getDeepOlderThan, getFirstborn, getNewest, getNode, getOlderSiblings, getYoungerSiblings, markPending, Post, addNode, GraphNodePoke } from '@urbit/api/graph';
|
||||
import { GraphReducer, reduceDm } from '../reducers/graph-update';
|
||||
import _ from 'lodash';
|
||||
import { clone } from '../lib/util';
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
archive,
|
||||
BigIntOrderedMap,
|
||||
HarkBin,
|
||||
markCountAsRead,
|
||||
NotificationGraphConfig,
|
||||
@ -15,7 +16,6 @@ import {
|
||||
import { Poke } from '@urbit/http-api';
|
||||
import { patp2dec } from 'urbit-ob';
|
||||
import _ from 'lodash';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import api from '~/logic/api';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Association, Associations, MetadataUpdatePreview } from '@urbit/api/metadata';
|
||||
import { Association, Associations, MetadataUpdatePreview } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
|
@ -16,8 +16,7 @@ import {
|
||||
import { useCallback } from 'react';
|
||||
import { reduceUpdate } from '../reducers/settings-update';
|
||||
import airlock from '~/logic/api';
|
||||
import { Contact, getDeskSettings, Value } from '@urbit/api';
|
||||
import { putEntry } from '@urbit/api/settings';
|
||||
import { Contact, getDeskSettings, putEntry, Value } from '@urbit/api';
|
||||
|
||||
export interface ShortcutMapping {
|
||||
cycleForward: string;
|
||||
|
@ -3,7 +3,7 @@ import { Meta, Story } from '@storybook/react';
|
||||
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import { InviteItem, InviteItemProps } from '~/views/components/Invite';
|
||||
import { JoinProgress } from '@urbit/api/groups';
|
||||
import { JoinProgress } from '@urbit/api';
|
||||
|
||||
export default {
|
||||
title: 'Notifications/Invite',
|
||||
|
@ -4,8 +4,7 @@ import { withDesign } from 'storybook-addon-designs';
|
||||
|
||||
import { Col, Row } from '@tlon/indigo-react';
|
||||
import { LinkBlockItem } from '~/views/apps/links/components/LinkBlockItem';
|
||||
import { createPost, GraphNode } from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import { BigIntOrderedMap, createPost, GraphNode } from '@urbit/api';
|
||||
|
||||
export default {
|
||||
title: 'Collections/BlockItem',
|
||||
|
@ -4,8 +4,7 @@ import { withDesign } from 'storybook-addon-designs';
|
||||
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import { LinkDetail } from '~/views/apps/links/components/LinkDetail';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import { GraphNode } from '@urbit/api';
|
||||
import { BigIntOrderedMap, GraphNode } from '@urbit/api';
|
||||
import useMetadataState from '~/logic/state/metadata';
|
||||
import { makeComment } from '~/logic/lib/fixtures';
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { ContactUpdate, GroupUpdate, InviteUpdate, MetadataUpdate } from '@urbit/api';
|
||||
import { SettingsUpdate } from '@urbit/api/settings';
|
||||
import { ContactUpdate, GroupUpdate, InviteUpdate, MetadataUpdate, SettingsUpdate } from '@urbit/api';
|
||||
import { ConnectionStatus } from './connection';
|
||||
import { LaunchUpdate, WeatherState } from './launch-update';
|
||||
import { LocalUpdate } from './local-update';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Content, createPost, fetchIsAllowed, Post, removePosts, deSig } from '@urbit/api';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, Content, createPost, fetchIsAllowed, Post, removePosts, deSig } from '@urbit/api';
|
||||
import { BigInteger } from 'big-integer';
|
||||
import React, {
|
||||
ReactElement, useCallback,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Box, Center, Col, LoadingSpinner, Text } from '@tlon/indigo-react';
|
||||
import { deSig, Group } from '@urbit/api';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, deSig, Group } from '@urbit/api';
|
||||
import bigInt from 'big-integer';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Link, Route, Switch, useLocation } from 'react-router-dom';
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { Col, Row, Text } from '@tlon/indigo-react';
|
||||
import { Association, Graph, GraphNode, markEachAsRead } from '@urbit/api';
|
||||
import { Association, BigIntOrderedMap, Graph, GraphNode, markEachAsRead } from '@urbit/api';
|
||||
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
||||
import _ from 'lodash';
|
||||
import { useResize } from '~/logic/lib/useResize';
|
||||
import { LinkBlockItem } from './LinkBlockItem';
|
||||
import { LinkBlockInput } from './LinkBlockInput';
|
||||
import useLocalState from '~/logic/state/local';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import bigInt from 'big-integer';
|
||||
import airlock from '~/logic/api';
|
||||
import useHarkState, { selHarkGraph } from '~/logic/state/hark';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Box, Center, Col, Text } from '@tlon/indigo-react';
|
||||
import React from 'react';
|
||||
import useHarkState, { HarkState } from '~/logic/state/hark';
|
||||
import { harkBinToId, HarkLid, Timebox } from '../../../../../npm/api/dist';
|
||||
import { harkBinToId, HarkLid, Timebox } from '@urbit/api';
|
||||
import { Notification } from './notification';
|
||||
|
||||
const unseenLid = { unseen: null };
|
||||
|
@ -3,7 +3,7 @@ import { Box, Row, Text } from '@tlon/indigo-react';
|
||||
import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction';
|
||||
import Author from '~/views/components/Author';
|
||||
import { useHistory } from 'react-router';
|
||||
import { acceptDm, declineDm } from '@urbit/api/graph';
|
||||
import { acceptDm, declineDm } from '@urbit/api';
|
||||
import airlock from '~/logic/api';
|
||||
|
||||
export function PendingDm(props: { ship: string; }) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Box, Col, Icon, Image, Row, Text } from '@tlon/indigo-react';
|
||||
import { Group } from '@urbit/api';
|
||||
import { GraphNode } from '@urbit/api/graph';
|
||||
import { Group, GraphNode } from '@urbit/api';
|
||||
import React from 'react';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { addNodes, Association } from '@urbit/api';
|
||||
import { Graph } from '@urbit/api/graph';
|
||||
import { addNodes, Association, Graph } from '@urbit/api';
|
||||
import { FormikHelpers } from 'formik';
|
||||
import React from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Action, Box, Col, Icon, Row, Text } from '@tlon/indigo-react';
|
||||
import { Group, removePosts } from '@urbit/api';
|
||||
import { GraphNode } from '@urbit/api/graph';
|
||||
import { GraphNode, Group, removePosts } from '@urbit/api';
|
||||
import bigInt from 'big-integer';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { roleForShip } from '~/logic/lib/group';
|
||||
|
@ -6,8 +6,7 @@ import {
|
||||
ErrorLabel, Icon, Label,
|
||||
Row, Text
|
||||
} from '@tlon/indigo-react';
|
||||
import { OpenPolicy } from '@urbit/api';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, OpenPolicy } from '@urbit/api';
|
||||
import { FieldArray, useFormikContext } from 'formik';
|
||||
import _ from 'lodash';
|
||||
import React, { ReactElement, useMemo, useState } from 'react';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { JoinRequest } from '@urbit/api';
|
||||
import { Invite } from '@urbit/api/invite';
|
||||
import { Invite, JoinRequest } from '@urbit/api';
|
||||
import React from 'react';
|
||||
import { usePreview } from '~/logic/state/metadata';
|
||||
import { GroupInvite } from './Group';
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { BigInteger } from 'big-integer';
|
||||
import React from 'react';
|
||||
import VirtualScroller, { VirtualScrollerProps } from './VirtualScroller';
|
||||
|
||||
import { arrToString } from '@urbit/api/lib/BigIntArrayOrderedMap';
|
||||
import { FlatGraphNode } from '@urbit/api';
|
||||
import { arrToString, FlatGraphNode } from '@urbit/api';
|
||||
|
||||
type ThreadScrollerProps = Omit<
|
||||
VirtualScrollerProps<BigInteger[], FlatGraphNode>,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Box, Center, Col, Text } from '@tlon/indigo-react';
|
||||
import { joinGraph } from '@urbit/api/graph';
|
||||
import { Association, GraphConfig } from '@urbit/api/metadata';
|
||||
import { Association, GraphConfig, joinGraph } from '@urbit/api';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useQuery } from '~/logic/lib/useQuery';
|
||||
|
@ -5,9 +5,7 @@ import {
|
||||
Text
|
||||
} from '@tlon/indigo-react';
|
||||
import _ from 'lodash';
|
||||
import { changePolicy, deSig, Enc } from '@urbit/api';
|
||||
import { Group, GroupPolicy } from '@urbit/api/groups';
|
||||
import { Association, metadataEdit, MetadataEditField } from '@urbit/api/metadata';
|
||||
import { Association, changePolicy, deSig, Enc, Group, GroupPolicy, metadataEdit, MetadataEditField } from '@urbit/api';
|
||||
import { Form, Formik, FormikHelpers } from 'formik';
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Box, Button, Col, Text } from '@tlon/indigo-react';
|
||||
import { deSig } from '@urbit/api';
|
||||
import { Group } from '@urbit/api/groups';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, deSig, Group } from '@urbit/api';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { resourceFromPath, roleForShip } from '~/logic/lib/group';
|
||||
|
@ -4,8 +4,7 @@ import {
|
||||
|
||||
Text
|
||||
} from '@tlon/indigo-react';
|
||||
import { ignoreGroup, listenGroup } from '@urbit/api';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, ignoreGroup, listenGroup } from '@urbit/api';
|
||||
import React from 'react';
|
||||
import useHarkState from '~/logic/state/hark';
|
||||
import { StatelessAsyncToggle } from '~/views/components/StatelessAsyncToggle';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Button, Icon, Row, Text } from '@tlon/indigo-react';
|
||||
import { disableGroupFeed } from '@urbit/api/graph';
|
||||
import { disableGroupFeed } from '@urbit/api';
|
||||
import React, { useState } from 'react';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import { resourceFromPath } from '~/logic/lib/group';
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { Box, Col } from '@tlon/indigo-react';
|
||||
import { Association, FlatGraph, FlatGraphNode, Group } from '@urbit/api';
|
||||
import { arrToString, Association, FlatGraph, FlatGraphNode, Group } from '@urbit/api';
|
||||
import bigInt from 'big-integer';
|
||||
import React from 'react';
|
||||
import { RouteComponentProps, useHistory } from 'react-router';
|
||||
import { resourceFromPath } from '~/logic/lib/group';
|
||||
import {
|
||||
arrToString
|
||||
} from '@urbit/api/lib/BigIntArrayOrderedMap';
|
||||
import { keyEq, ThreadScroller } from '~/views/components/ThreadScroller';
|
||||
import PostItem from './PostItem/PostItem';
|
||||
import PostInput from './PostInput';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Action, Col, Icon, Row } from '@tlon/indigo-react';
|
||||
import { Association, Post } from '@urbit/api';
|
||||
import { Association, Post, removePosts } from '@urbit/api';
|
||||
import React, { ReactElement } from 'react';
|
||||
import { getPermalinkForGraph } from '~/logic/lib/permalinks';
|
||||
import { useCopy } from '~/logic/lib/useCopy';
|
||||
@ -8,7 +8,6 @@ import { resourceFromPath } from '~/logic/lib/group';
|
||||
import Author from '~/views/components/Author';
|
||||
import { Dropdown } from '~/views/components/Dropdown';
|
||||
import airlock from '~/logic/api';
|
||||
import { removePosts } from '@urbit/api/graph';
|
||||
interface PostHeaderProps {
|
||||
post: Post;
|
||||
association: Association;
|
||||
|
@ -6,11 +6,10 @@ import React, {
|
||||
} from 'react';
|
||||
import { resourceFromPath } from '~/logic/lib/group';
|
||||
import { Loading } from '~/views/components/Loading';
|
||||
import { arrToString } from '@urbit/api/lib/BigIntArrayOrderedMap';
|
||||
import useGraphState from '~/logic/state/graph';
|
||||
import PostFlatFeed from './PostFlatFeed';
|
||||
import PostInput from './PostInput';
|
||||
import { Association, deSig, PermVariation } from '@urbit/api';
|
||||
import { arrToString, Association, deSig, PermVariation } from '@urbit/api';
|
||||
import { useParams, Switch, Route } from 'react-router';
|
||||
import { useGroupForAssoc } from '~/logic/state/group';
|
||||
|
||||
|
@ -5,8 +5,7 @@ import {
|
||||
|
||||
Row, Text
|
||||
} from '@tlon/indigo-react';
|
||||
import { invite } from '@urbit/api/groups';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, invite } from '@urbit/api';
|
||||
import { Form, Formik } from 'formik';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Box, Col, Text } from '@tlon/indigo-react';
|
||||
import { invite } from '@urbit/api/groups';
|
||||
import { invite } from '@urbit/api';
|
||||
import { Form, Formik } from 'formik';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
|
@ -6,10 +6,7 @@ import {
|
||||
|
||||
StatelessTextInput as Input, Text
|
||||
} from '@tlon/indigo-react';
|
||||
import { Contact, Contacts } from '@urbit/api/contacts';
|
||||
import { addTag, removeMembers, changePolicy, Group, removeTag, RoleTags } from '@urbit/api/groups';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { deSig } from '@urbit/api';
|
||||
import { addTag, Association, Contact, Contacts, changePolicy, deSig, Group, removeMembers, removeTag, RoleTags } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import f from 'lodash/fp';
|
||||
import React, {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Box, Col, Text } from '@tlon/indigo-react';
|
||||
import { Group } from '@urbit/api/groups';
|
||||
import { deSig } from '@urbit/api';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { Association, deSig, Group } from '@urbit/api';
|
||||
import React, { ReactElement, useCallback, useRef } from 'react';
|
||||
import { Link, Route, RouteComponentProps, Switch } from 'react-router-dom';
|
||||
import { resourceFromPath } from '~/logic/lib/group';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { AppName } from '@urbit/api';
|
||||
import { AppName, Association } from '@urbit/api';
|
||||
import React, { ReactElement } from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
|
@ -1,7 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { Box, Col, Icon, Text } from '@tlon/indigo-react';
|
||||
import { Association } from '@urbit/api/metadata';
|
||||
import { AppName } from '@urbit/api';
|
||||
import { AppName, Association } from '@urbit/api';
|
||||
import React, { ReactElement, ReactNode, useCallback, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
|
12
pkg/npm/api/.babelrc
Normal file
12
pkg/npm/api/.babelrc
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": "> 1%",
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": "3.19.1"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
1
pkg/npm/api/.gitignore
vendored
Normal file
1
pkg/npm/api/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
tmp
|
2
pkg/npm/api/deps.d.ts
vendored
2
pkg/npm/api/deps.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
|
||||
declare module "urbit-ob" {
|
||||
declare module 'urbit-ob' {
|
||||
|
||||
/**
|
||||
* Convert a @p-encoded string to a decimal-encoded string.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Patp } from '../lib';
|
||||
import BigIntOrderedMap from '../lib/BigIntOrderedMap';
|
||||
import BigIntArrayOrderedMap from '../lib/BigIntArrayOrderedMap';
|
||||
import { BigIntOrderedMap } from '../lib/BigIntOrderedMap';
|
||||
import { BigIntArrayOrderedMap } from '../lib/BigIntArrayOrderedMap';
|
||||
|
||||
export interface TextContent {
|
||||
text: string;
|
||||
|
@ -1,5 +1,3 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Enc, Path, Patp, PatpNoSig, Poke, Thread } from '../lib/types';
|
||||
import { Group, GroupPolicy, GroupPolicyDiff, GroupUpdateAddMembers, GroupUpdateAddTag, GroupUpdateChangePolicy, GroupUpdateRemoveGroup, GroupUpdateRemoveMembers, GroupUpdateRemoveTag, Resource, RoleTags, Tag } from './types';
|
||||
import { GroupUpdate } from './update';
|
||||
@ -97,6 +95,10 @@ export const changePolicy = (
|
||||
}
|
||||
});
|
||||
|
||||
export const makeResource = (ship: string, name: string) => {
|
||||
return { ship, name };
|
||||
};
|
||||
|
||||
export const join = (
|
||||
ship: string,
|
||||
name: string,
|
||||
@ -181,30 +183,32 @@ export const roleForShip = (
|
||||
const roleShips = group?.tags?.role?.[role];
|
||||
return roleShips && roleShips.has(ship) ? role : currRole;
|
||||
}, undefined as RoleTags | undefined);
|
||||
}
|
||||
};
|
||||
|
||||
export const resourceFromPath = (path: Path): Resource => {
|
||||
const [, , ship, name] = path.split('/');
|
||||
return { ship, name };
|
||||
}
|
||||
|
||||
export const makeResource = (ship: string, name: string) => {
|
||||
return { ship, name };
|
||||
}
|
||||
};
|
||||
|
||||
export const isWriter = (group: Group, resource: string, ship: string) => {
|
||||
const writers: Set<string> | undefined = _.get(
|
||||
group,
|
||||
['tags', 'graph', resource, 'writers'],
|
||||
undefined
|
||||
);
|
||||
const graph = group.tags?.graph;
|
||||
const writers: Set<string> | undefined = graph && (graph[resource] as any)?.writers;
|
||||
const admins = group?.tags?.role?.admin ?? new Set();
|
||||
if (_.isUndefined(writers)) {
|
||||
if (typeof writers === 'undefined') {
|
||||
return true;
|
||||
} else {
|
||||
return writers.has(ship) || admins.has(ship);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const isHost = (
|
||||
resource: string,
|
||||
ship: string
|
||||
): boolean => {
|
||||
const [, , host] = resource.split('/');
|
||||
|
||||
return ship === host;
|
||||
};
|
||||
|
||||
export const isChannelAdmin = (
|
||||
group: Group,
|
||||
@ -218,13 +222,4 @@ export const isChannelAdmin = (
|
||||
role === 'admin' ||
|
||||
role === 'moderator'
|
||||
);
|
||||
}
|
||||
|
||||
export const isHost = (
|
||||
resource: string,
|
||||
ship: string
|
||||
): boolean => {
|
||||
const [, , host] = resource.split('/');
|
||||
|
||||
return ship === host;
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PatpNoSig, Path, Jug, ShipRank, Enc } from '../lib';
|
||||
import { PatpNoSig, Path, ShipRank, Enc } from '../lib';
|
||||
import { roleTags } from './index';
|
||||
|
||||
export type RoleTags = typeof roleTags[number];
|
||||
@ -173,5 +173,3 @@ export type GroupUpdate =
|
||||
| GroupUpdateInitialGroup;
|
||||
|
||||
export type GroupAction = Omit<GroupUpdate, 'initialGroup' | 'initial'>;
|
||||
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Poke, Scry } from '../lib';
|
||||
import { Vats, Vat } from './types';
|
||||
import _ from 'lodash';
|
||||
|
||||
export const getVats: Scry = {
|
||||
app: 'hood',
|
||||
@ -98,13 +97,17 @@ export function getBlockers(vats: Vats): string[] {
|
||||
if(!blockedOn) {
|
||||
return blockers;
|
||||
}
|
||||
_.forEach(_.omit(vats, 'base'), (vat, desk) => {
|
||||
// assuming only %zuse
|
||||
const kelvins = _.map((vat.arak.rail?.next || []), n => n.weft.kelvin);
|
||||
if(!(kelvins.includes(blockedOn))) {
|
||||
blockers.push(desk);
|
||||
}
|
||||
});
|
||||
|
||||
Object.entries(vats)
|
||||
.filter(([desk]) => desk !== 'base')
|
||||
.forEach(([desk, vat]) => {
|
||||
// assuming only %zuse
|
||||
const woofs = vat.arak.rail?.next || [];
|
||||
const kelvins = woofs.map(n => n.weft.kelvin);
|
||||
if(!(kelvins.includes(blockedOn))) {
|
||||
blockers.push(desk);
|
||||
}
|
||||
});
|
||||
|
||||
return blockers;
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ export * as groups from './groups';
|
||||
export * from './hark';
|
||||
export * as hark from './hark';
|
||||
export * from './invite';
|
||||
export * as invite from './invite';
|
||||
// this conflicts with /groups/lib invite
|
||||
// export * as invite from './invite';
|
||||
export * from './metadata';
|
||||
export * as metadata from './metadata';
|
||||
export * from './settings';
|
||||
@ -16,6 +17,7 @@ export * from './s3';
|
||||
export * as s3 from './s3';
|
||||
export * from './lib';
|
||||
export * from './lib/BigIntOrderedMap';
|
||||
export * from './lib/BigIntArrayOrderedMap';
|
||||
export * as hood from './hood';
|
||||
export * from './hood';
|
||||
export * as docket from './docket';
|
||||
|
@ -51,7 +51,7 @@ export function sortBigIntArr(a: BigInteger[], b: BigInteger[]) {
|
||||
return bLen - aLen;
|
||||
}
|
||||
|
||||
export default class BigIntArrayOrderedMap<V> implements Iterable<[BigInteger[], V]> {
|
||||
export class BigIntArrayOrderedMap<V> implements Iterable<[BigInteger[], V]> {
|
||||
root: Record<string, V> = {}
|
||||
cachedIter: [BigInteger[], V][] | null = null;
|
||||
[immerable] = true;
|
||||
|
@ -14,7 +14,7 @@ function sortBigInt(a: BigInteger, b: BigInteger) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
export default class BigIntOrderedMap<V> implements Iterable<[BigInteger, V]> {
|
||||
export class BigIntOrderedMap<V> implements Iterable<[BigInteger, V]> {
|
||||
root: Record<string, V> = {}
|
||||
cachedIter: [BigInteger, V][] | null = null;
|
||||
[immerable] = true;
|
||||
|
@ -1,5 +1,3 @@
|
||||
import _ from "lodash";
|
||||
import f from "lodash/fp";
|
||||
import bigInt, { BigInteger } from "big-integer";
|
||||
|
||||
import { Resource } from "../groups/types";
|
||||
@ -9,6 +7,36 @@ const DA_UNIX_EPOCH = bigInt("170141184475152167957503069145530368000"); // `@ud
|
||||
|
||||
const DA_SECOND = bigInt("18446744073709551616"); // `@ud` ~s1
|
||||
|
||||
function chunk<T>(arr: T[], size: number): T[][] {
|
||||
let chunk: T[] = [];
|
||||
let newArray = [chunk];
|
||||
|
||||
for (let i = 0;i < arr.length;i++) {
|
||||
if (chunk.length < size) {
|
||||
chunk.push(arr[i])
|
||||
} else {
|
||||
chunk = [arr[i]]
|
||||
newArray.push(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
function dropWhile<T>(arr: T[], pred: (x: T) => boolean): T[] {
|
||||
const newArray = arr.slice();
|
||||
|
||||
for (const item of arr) {
|
||||
if (pred(item)) {
|
||||
newArray.shift();
|
||||
} else {
|
||||
return newArray;
|
||||
}
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a bigint representing an urbit date, returns a unix timestamp.
|
||||
*
|
||||
@ -48,17 +76,11 @@ export function udToDec(ud: string): string {
|
||||
}
|
||||
|
||||
export function decToUd(str: string): string {
|
||||
return _.trimStart(
|
||||
f.flow(
|
||||
f.split(""),
|
||||
f.reverse,
|
||||
f.chunk(3),
|
||||
f.map(f.flow(f.reverse, f.join(""))),
|
||||
f.reverse,
|
||||
f.join(".")
|
||||
)(str),
|
||||
"0."
|
||||
);
|
||||
const transform = chunk(str.split('').reverse(), 3)
|
||||
.map(group => group.reverse().join(''))
|
||||
.reverse()
|
||||
.join('.')
|
||||
return transform.replace(/^[0\.]+/g, '');
|
||||
}
|
||||
|
||||
export function resourceAsPath(resource: Resource): string {
|
||||
@ -161,14 +183,11 @@ export function uxToHex(ux: string) {
|
||||
}
|
||||
|
||||
export const hexToUx = (hex: string): string => {
|
||||
const ux = f.flow(
|
||||
f.dropWhile(y => y === '0'),
|
||||
f.reverse,
|
||||
f.chunk(4),
|
||||
f.map(x => x.reverse().join('')),
|
||||
f.reverse,
|
||||
f.join('.')
|
||||
)(hex.split('')) || '0';
|
||||
const nonZeroChars = dropWhile(hex.split(''), y => y === '0');
|
||||
const ux = chunk(nonZeroChars.reverse(), 4).map(x => {
|
||||
return x.reverse().join('');
|
||||
}).reverse().join('.') || '0';
|
||||
|
||||
return `0x${ux}`;
|
||||
};
|
||||
|
||||
@ -210,21 +229,6 @@ export function stringToTa(str: string): string {
|
||||
return "~." + out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats a numbers as a `@ud` inserting dot where needed
|
||||
*/
|
||||
export function numToUd(num: number): string {
|
||||
return f.flow(
|
||||
f.split(''),
|
||||
f.reverse,
|
||||
f.chunk(3),
|
||||
f.reverse,
|
||||
f.map(s => s.join('')),
|
||||
f.join('.')
|
||||
)(num.toString())
|
||||
}
|
||||
|
||||
export const buntPost = (): Post => ({
|
||||
author: '',
|
||||
contents: [],
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Martian embassy
|
||||
*/
|
||||
|
||||
import BigIntOrderedMap from "./BigIntOrderedMap";
|
||||
import { BigIntOrderedMap } from "./BigIntOrderedMap";
|
||||
|
||||
// an urbit style path rendered as string
|
||||
export type Path = string;
|
||||
|
3602
pkg/npm/api/package-lock.json
generated
3602
pkg/npm/api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,39 +1,52 @@
|
||||
{
|
||||
"name": "@urbit/api",
|
||||
"version": "1.4.1",
|
||||
"description": "",
|
||||
"version": "2.1.0",
|
||||
"description": "A library that provides bindings and types for Urbit's various userspace desks",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/urbit/urbit.git",
|
||||
"directory": "pkg/npm/api"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d",
|
||||
"type": "module",
|
||||
"main": "dist/cjs/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
"jsdelivr": "dist/urbit-api.min.js",
|
||||
"unpkg": "dist/urbit-api.min.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "echo \"No test specified\" && exit 0",
|
||||
"watch": "tsc -p tsconfig.json --watch",
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"clean": "rm -rf dist/*",
|
||||
"prepare": "npm run build"
|
||||
"build": "npm run clean && rollup -c && npx tsc -p tsconfig.json",
|
||||
"prepare": "npm run build",
|
||||
"watch": "rollup -c -w",
|
||||
"clean": "rm -rf dist/* types/*"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@urbit/eslint-config": "^1.0.3",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"big-integer": "^1.6.48",
|
||||
"core-js": "^3.19.1",
|
||||
"immer": "^9.0.1",
|
||||
"lodash": "^4.17.20",
|
||||
"urbit-ob": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.0",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-commonjs": "^21.0.1",
|
||||
"@rollup/plugin-node-resolve": "^13.0.6",
|
||||
"@types/node": "^15.12.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.28.2",
|
||||
"@typescript-eslint/parser": "^4.28.2",
|
||||
"@urbit/eslint-config": "^1.0.3",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"onchange": "^7.1.0",
|
||||
"rollup": "^2.59.0",
|
||||
"rollup-plugin-analyzer": "^4.0.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-typescript2": "^0.30.0",
|
||||
"typescript": "^4.3.2"
|
||||
}
|
||||
}
|
||||
|
76
pkg/npm/api/rollup.config.ts
Normal file
76
pkg/npm/api/rollup.config.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import commonJS from '@rollup/plugin-commonjs';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import typescript from 'rollup-plugin-typescript2';
|
||||
import analyze from 'rollup-plugin-analyzer'
|
||||
|
||||
const input = ['./index.ts'];
|
||||
|
||||
// Skip certain warnings
|
||||
function onwarn(warning) {
|
||||
if (warning.code === 'THIS_IS_UNDEFINED') {
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn(warning.message);
|
||||
}
|
||||
|
||||
export default [
|
||||
{
|
||||
input,
|
||||
onwarn,
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||
}),
|
||||
commonJS(),
|
||||
typescript(),
|
||||
babel({
|
||||
babelHelpers: 'bundled',
|
||||
exclude: ['node_modules/**']
|
||||
}),
|
||||
terser({
|
||||
ecma: 2017,
|
||||
compress: true,
|
||||
mangle: true
|
||||
})
|
||||
],
|
||||
output: {
|
||||
file: 'dist/urbit-api.min.js',
|
||||
format: 'umd',
|
||||
name: 'UrbitAPI', // this is the name of the global object
|
||||
esModule: false,
|
||||
exports: 'named',
|
||||
sourcemap: true
|
||||
}
|
||||
},
|
||||
{
|
||||
input,
|
||||
onwarn,
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx']
|
||||
}),
|
||||
commonJS(),
|
||||
typescript(),
|
||||
analyze({
|
||||
limit: 10
|
||||
})
|
||||
],
|
||||
output: [
|
||||
{
|
||||
dir: 'dist/esm',
|
||||
format: 'esm',
|
||||
exports: 'named',
|
||||
sourcemap: true
|
||||
},
|
||||
{
|
||||
dir: 'dist/cjs',
|
||||
format: 'cjs',
|
||||
exports: 'named',
|
||||
sourcemap: true
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "./dist",
|
||||
"module": "ES2020",
|
||||
"outDir": "./tmp",
|
||||
"module": "ESNext",
|
||||
"noImplicitAny": true,
|
||||
"target": "ES2017",
|
||||
"target": "ESNext",
|
||||
"pretty": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
@ -14,6 +14,11 @@
|
||||
"strict": false,
|
||||
"noErrorTruncation": true
|
||||
},
|
||||
"exclude": ["node_modules", "./dist/**/*", "@types"],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"./dist/**/*",
|
||||
"./tmp/**/*",
|
||||
"rollup.config.ts"
|
||||
],
|
||||
"include": ["./*.ts"]
|
||||
}
|
||||
|
13
pkg/npm/http-api/.babelrc
Normal file
13
pkg/npm/http-api/.babelrc
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-typescript", //needed for .ts jest tests
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": "> 1%",
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": "3.19.1"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
4
pkg/npm/http-api/.gitignore
vendored
4
pkg/npm/http-api/.gitignore
vendored
@ -0,0 +1,4 @@
|
||||
dist
|
||||
node_modules
|
||||
coverage
|
||||
tmp
|
@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', {targets: {node: 'current'}}],
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
};
|
@ -1,98 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Demo</title>
|
||||
<script src="browser.js"></script>
|
||||
<script src="../dist/urbit-http-api.min.js"></script>
|
||||
<style>
|
||||
@import url("https://rsms.me/inter/inter.css");
|
||||
@font-face {
|
||||
font-family: "Source Code Pro";
|
||||
src: url("https://storage.googleapis.com/media.urbit.org/fonts/scp-regular.woff");
|
||||
font-weight: 400;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 70ch;
|
||||
padding: 2ch;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
#mylog {
|
||||
white-space: pre-wrap;
|
||||
padding: 2ch;
|
||||
background: black;
|
||||
color: white;
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
}
|
||||
#mylog div {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.chunk {
|
||||
border-bottom: 1px dashed currentColor;
|
||||
}
|
||||
@import url('https://rsms.me/inter/inter.css');
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
src: url('https://storage.googleapis.com/media.urbit.org/fonts/scp-regular.woff');
|
||||
font-weight: 400;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 70ch;
|
||||
padding: 2ch;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
#mylog {
|
||||
white-space: pre-wrap;
|
||||
padding: 2ch;
|
||||
background: black;
|
||||
color: white;
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
}
|
||||
#mylog div {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.chunk {
|
||||
border-bottom: 1px dashed currentColor;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
</head>
|
||||
<body>
|
||||
<details>
|
||||
<summary>Show instructions</summary>
|
||||
<p>Assuming you are running a fakezod on port 8080, run</p>
|
||||
<code id="instructions">|cors-approve '{window.location.origin}'</code>
|
||||
<p>in its dojo.</p>
|
||||
<p>Press the button to run the code below. Output will be logged. You should see <code>< ~zod: opening airlock</code> in your dojo.</code> Create a chat and send a message to see the events logged.</p>
|
||||
<pre>window.airlock = await Urbit.authenticate({
|
||||
<summary>Show instructions</summary>
|
||||
<p>Assuming you are running a fakezod on port 8080, run</p>
|
||||
<code id="instructions">|cors-approve '{window.location.origin}'</code>
|
||||
<p>in its dojo.</p>
|
||||
<p>
|
||||
Press the button to run the code below. Output will be logged. You
|
||||
should see <code>< ~zod: opening airlock</code> in your dojo. Create
|
||||
a chat and send a message to see the events logged.
|
||||
</p>
|
||||
<pre>
|
||||
window.airlock = await UrbitHttpApi.Urbit.authenticate({
|
||||
ship: 'zod',
|
||||
url: 'localhost:8080',
|
||||
code: 'lidlut-tabwed-pillex-ridrup',
|
||||
verbose: true
|
||||
});
|
||||
window.airlock.subscribe('chat-view', '/primary', { event: console.log });</pre>
|
||||
window.airlock.subscribe({
|
||||
app: 'graph-store',
|
||||
path: '/updates',
|
||||
event: console.log
|
||||
});</pre
|
||||
>
|
||||
</details>
|
||||
|
||||
<button id="blastoff" onclick="blastOff()">Blast Off</button>
|
||||
<pre id="mylog">
|
||||
|
||||
</pre>
|
||||
</body>
|
||||
<script>
|
||||
<pre id="mylog"></pre>
|
||||
</body>
|
||||
<script>
|
||||
var baseLogFunction = console.log;
|
||||
console.log = function(){
|
||||
baseLogFunction.apply(console, arguments);
|
||||
var chunk = document.createElement('div');
|
||||
chunk.className = 'chunk';
|
||||
console.log = function () {
|
||||
baseLogFunction.apply(console, arguments);
|
||||
var chunk = document.createElement('div');
|
||||
chunk.className = 'chunk';
|
||||
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
for(var i=0;i<args.length;i++){
|
||||
const val = typeof args[i] === 'string' ? args[i] : JSON.stringify(args[i]);
|
||||
var node = createLogNode(val);
|
||||
chunk.appendChild(node);
|
||||
}
|
||||
document.querySelector("#mylog").insertBefore(chunk, document.querySelector("#mylog").firstChild);
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
const val =
|
||||
typeof args[i] === 'string' ? args[i] : JSON.stringify(args[i]);
|
||||
var node = createLogNode(val);
|
||||
chunk.appendChild(node);
|
||||
}
|
||||
document
|
||||
.querySelector('#mylog')
|
||||
.insertBefore(chunk, document.querySelector('#mylog').firstChild);
|
||||
};
|
||||
|
||||
function createLogNode(message) {
|
||||
var node = document.createElement('div');
|
||||
node.className = 'message';
|
||||
var textNode = document.createTextNode(message);
|
||||
node.appendChild(textNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
function createLogNode(message){
|
||||
var node = document.createElement("div");
|
||||
node.className = 'message';
|
||||
var textNode = document.createTextNode(message);
|
||||
node.appendChild(textNode);
|
||||
return node;
|
||||
}
|
||||
|
||||
window.onerror = function(message, url, linenumber) {
|
||||
console.log("JavaScript error: " + message + " on line " +
|
||||
linenumber + " for " + url);
|
||||
}
|
||||
window.onerror = function (message, url, linenumber) {
|
||||
console.log(
|
||||
'JavaScript error: ' +
|
||||
message +
|
||||
' on line ' +
|
||||
linenumber +
|
||||
' for ' +
|
||||
url
|
||||
);
|
||||
};
|
||||
const instructions = document.getElementById('instructions');
|
||||
instructions.innerText = instructions.innerText.replace('{window.location.origin}', window.location.origin);
|
||||
instructions.innerText = instructions.innerText.replace(
|
||||
'{window.location.origin}',
|
||||
window.location.origin
|
||||
);
|
||||
async function blastOff() {
|
||||
window.airlock = await Urbit.authenticate({
|
||||
ship: 'zod',
|
||||
url: 'localhost:8080',
|
||||
code: 'lidlut-tabwed-pillex-ridrup',
|
||||
verbose: true
|
||||
});
|
||||
window.airlock.subscribe('chat-view', '/primary', { event: console.log });
|
||||
document.body.removeChild(document.getElementById('blastoff'))
|
||||
window.airlock = await UrbitHttpApi.Urbit.authenticate({
|
||||
ship: 'zod',
|
||||
url: 'localhost',
|
||||
code: 'lidlut-tabwed-pillex-ridrup',
|
||||
verbose: true,
|
||||
});
|
||||
window.airlock.subscribe({
|
||||
app: 'graph-store',
|
||||
path: '/updates',
|
||||
event: console.log,
|
||||
});
|
||||
document.body.removeChild(document.getElementById('blastoff'));
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
</script>
|
||||
</html>
|
||||
|
@ -23,7 +23,7 @@ module.exports = {
|
||||
// collectCoverageFrom: undefined,
|
||||
|
||||
// The directory where Jest should output its coverage files
|
||||
coverageDirectory: "coverage",
|
||||
coverageDirectory: 'coverage',
|
||||
|
||||
// An array of regexp pattern strings used to skip coverage collection
|
||||
// coveragePathIgnorePatterns: [
|
||||
@ -137,7 +137,7 @@ module.exports = {
|
||||
// snapshotSerializers: [],
|
||||
|
||||
// The test environment that will be used for testing
|
||||
testEnvironment: "jsdom",
|
||||
testEnvironment: 'jsdom',
|
||||
|
||||
// Options that will be passed to the testEnvironment
|
||||
// testEnvironmentOptions: {},
|
||||
@ -166,7 +166,7 @@ module.exports = {
|
||||
// testRunner: "jest-circus/runner",
|
||||
|
||||
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
|
||||
testURL: "http://localhost",
|
||||
testURL: 'http://localhost',
|
||||
|
||||
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
|
||||
// timers: "real",
|
15968
pkg/npm/http-api/package-lock.json
generated
15968
pkg/npm/http-api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@urbit/http-api",
|
||||
"version": "1.3.1",
|
||||
"version": "2.1.0",
|
||||
"license": "MIT",
|
||||
"description": "Library to interact with an Urbit ship over HTTP",
|
||||
"repository": {
|
||||
@ -8,18 +8,21 @@
|
||||
"url": "ssh://git@github.com/urbit/urbit.git",
|
||||
"directory": "pkg/npm/http-api"
|
||||
},
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"main": "dist/cjs/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
"jsdelivr": "dist/urbit-http-api.min.js",
|
||||
"unpkg": "dist/urbit-http-api.min.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"src"
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"build": "npm run clean && rollup -c && npx tsc -p tsconfig.json",
|
||||
"prepare": "npm run build",
|
||||
"watch": "tsc -p tsconfig.json --watch",
|
||||
"clean": "rm -rf dist/*"
|
||||
"watch": "rollup -c -w",
|
||||
"clean": "rm -rf dist/* types/*"
|
||||
},
|
||||
"prettier": {
|
||||
"printWidth": 80,
|
||||
@ -29,12 +32,12 @@
|
||||
},
|
||||
"author": "",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.12.1",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"@babel/preset-typescript": "^7.12.1",
|
||||
"@babel/core": "^7.15.8",
|
||||
"@babel/preset-env": "^7.15.8",
|
||||
"@babel/preset-typescript": "^7.16.0",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-commonjs": "^21.0.1",
|
||||
"@rollup/plugin-node-resolve": "^13.0.6",
|
||||
"@types/browser-or-node": "^1.2.0",
|
||||
"@types/eventsource": "^1.1.5",
|
||||
"@types/jest": "^26.0.24",
|
||||
@ -42,29 +45,22 @@
|
||||
"@typescript-eslint/eslint-plugin": "^4.7.0",
|
||||
"@typescript-eslint/parser": "^4.7.0",
|
||||
"babel-jest": "^27.0.6",
|
||||
"babel-loader": "^8.2.1",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"cross-fetch": "^3.1.4",
|
||||
"event-target-polyfill": "0.0.3",
|
||||
"fast-text-encoding": "^1.0.3",
|
||||
"jest": "^27.0.6",
|
||||
"onchange": "^7.1.0",
|
||||
"tslib": "^2.0.3",
|
||||
"rollup": "^2.59.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-typescript2": "^0.30.0",
|
||||
"typescript": "^3.9.7",
|
||||
"util": "^0.12.3",
|
||||
"web-streams-polyfill": "^3.0.3",
|
||||
"webpack": "^5.4.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.0",
|
||||
"yet-another-abortcontroller-polyfill": "0.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@microsoft/fetch-event-source": "^2.0.0",
|
||||
"browser-or-node": "^1.3.0",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"buffer": "^6.0.3",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.1.1"
|
||||
"core-js": "^3.19.1"
|
||||
}
|
||||
}
|
||||
|
72
pkg/npm/http-api/rollup.config.ts
Normal file
72
pkg/npm/http-api/rollup.config.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import commonJS from '@rollup/plugin-commonjs';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import typescript from 'rollup-plugin-typescript2';
|
||||
|
||||
const input = ['src/index.ts'];
|
||||
|
||||
// Skip certain warnings
|
||||
function onwarn(warning) {
|
||||
if (warning.code === 'THIS_IS_UNDEFINED') {
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn(warning.message);
|
||||
}
|
||||
|
||||
export default [
|
||||
{
|
||||
input,
|
||||
onwarn,
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
}),
|
||||
commonJS(),
|
||||
typescript(),
|
||||
babel({
|
||||
babelHelpers: 'bundled',
|
||||
exclude: ['node_modules/**'],
|
||||
}),
|
||||
terser({
|
||||
ecma: 2017,
|
||||
compress: true,
|
||||
mangle: true,
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
file: `dist/urbit-http-api.min.js`,
|
||||
format: 'umd',
|
||||
name: 'UrbitHttpApi', // this is the name of the global object
|
||||
esModule: false,
|
||||
exports: 'named',
|
||||
sourcemap: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
input,
|
||||
onwarn,
|
||||
plugins: [
|
||||
nodeResolve({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
}),
|
||||
commonJS(),
|
||||
typescript(),
|
||||
],
|
||||
output: [
|
||||
{
|
||||
dir: 'dist/esm',
|
||||
format: 'esm',
|
||||
exports: 'named',
|
||||
sourcemap: true,
|
||||
},
|
||||
{
|
||||
dir: 'dist/cjs',
|
||||
format: 'cjs',
|
||||
exports: 'named',
|
||||
sourcemap: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
@ -1,8 +1,21 @@
|
||||
import { isBrowser, isNode } from 'browser-or-node';
|
||||
import { fetchEventSource, EventSourceMessage, EventStreamContentType } from '@microsoft/fetch-event-source';
|
||||
import {
|
||||
fetchEventSource,
|
||||
EventSourceMessage,
|
||||
} from '@microsoft/fetch-event-source';
|
||||
|
||||
import { Action, Scry, Thread, AuthenticationInterface, SubscriptionInterface, CustomEventHandler, PokeInterface, SubscriptionRequestInterface, headers, SSEOptions, PokeHandlers, Message, FatalError } from './types';
|
||||
import { uncamelize, hexString } from './utils';
|
||||
import {
|
||||
Scry,
|
||||
Thread,
|
||||
AuthenticationInterface,
|
||||
PokeInterface,
|
||||
SubscriptionRequestInterface,
|
||||
headers,
|
||||
SSEOptions,
|
||||
PokeHandlers,
|
||||
Message,
|
||||
} from './types';
|
||||
import { hexString } from './utils';
|
||||
|
||||
/**
|
||||
* A class for interacting with an urbit ship, given its URL and code
|
||||
@ -32,7 +45,7 @@ export class Urbit {
|
||||
|
||||
/**
|
||||
* A registry of requestId to successFunc/failureFunc
|
||||
*
|
||||
*
|
||||
* These functions are registered during a +poke and are executed
|
||||
* in the onServerEvent()/onServerError() callbacks. Only one of
|
||||
* the functions will be called, and the outstanding poke will be
|
||||
@ -43,16 +56,17 @@ export class Urbit {
|
||||
|
||||
/**
|
||||
* A registry of requestId to subscription functions.
|
||||
*
|
||||
*
|
||||
* These functions are registered during a +subscribe and are
|
||||
* executed in the onServerEvent()/onServerError() callbacks. The
|
||||
* event function will be called whenever a new piece of data on this
|
||||
* subscription is available, which may be 0, 1, or many times. The
|
||||
* disconnect function may be called exactly once.
|
||||
*/
|
||||
private outstandingSubscriptions: Map<number, SubscriptionRequestInterface> = new Map();
|
||||
private outstandingSubscriptions: Map<number, SubscriptionRequestInterface> =
|
||||
new Map();
|
||||
|
||||
/**
|
||||
/**
|
||||
* Our abort controller, used to close the connection
|
||||
*/
|
||||
private abort = new AbortController();
|
||||
@ -94,7 +108,7 @@ export class Urbit {
|
||||
credentials: 'include',
|
||||
accept: '*',
|
||||
headers,
|
||||
signal: this.abort.signal
|
||||
signal: this.abort.signal,
|
||||
};
|
||||
}
|
||||
|
||||
@ -102,15 +116,11 @@ export class Urbit {
|
||||
* Constructs a new Urbit connection.
|
||||
*
|
||||
* @param url The URL (with protocol and port) of the ship to be accessed. If
|
||||
* the airlock is running in a webpage served by the ship, this should just
|
||||
* the airlock is running in a webpage served by the ship, this should just
|
||||
* be the empty string.
|
||||
* @param code The access code for the ship at that address
|
||||
*/
|
||||
constructor(
|
||||
public url: string,
|
||||
public code?: string,
|
||||
public desk?: string
|
||||
) {
|
||||
constructor(public url: string, public code?: string, public desk?: string) {
|
||||
if (isBrowser) {
|
||||
window.addEventListener('beforeunload', this.delete);
|
||||
}
|
||||
@ -119,18 +129,27 @@ export class Urbit {
|
||||
|
||||
/**
|
||||
* All-in-one hook-me-up.
|
||||
*
|
||||
*
|
||||
* Given a ship, url, and code, this returns an airlock connection
|
||||
* that is ready to go. It `|hi`s itself to create the channel,
|
||||
* then opens the channel via EventSource.
|
||||
*
|
||||
*
|
||||
*/
|
||||
static async authenticate({ ship, url, code, verbose = false }: AuthenticationInterface) {
|
||||
static async authenticate({
|
||||
ship,
|
||||
url,
|
||||
code,
|
||||
verbose = false,
|
||||
}: AuthenticationInterface) {
|
||||
const airlock = new Urbit(`http://${url}`, code);
|
||||
airlock.verbose = verbose;
|
||||
airlock.ship = ship;
|
||||
await airlock.connect();
|
||||
await airlock.poke({ app: 'hood', mark: 'helm-hi', json: 'opening airlock' });
|
||||
await airlock.poke({
|
||||
app: 'hood',
|
||||
mark: 'helm-hi',
|
||||
json: 'opening airlock',
|
||||
});
|
||||
await airlock.eventSource();
|
||||
return airlock;
|
||||
}
|
||||
@ -141,13 +160,18 @@ export class Urbit {
|
||||
*/
|
||||
async connect(): Promise<void> {
|
||||
if (this.verbose) {
|
||||
console.log(`password=${this.code} `, isBrowser ? "Connecting in browser context at " + `${this.url}/~/login` : "Connecting from node context");
|
||||
console.log(
|
||||
`password=${this.code} `,
|
||||
isBrowser
|
||||
? 'Connecting in browser context at ' + `${this.url}/~/login`
|
||||
: 'Connecting from node context'
|
||||
);
|
||||
}
|
||||
return fetch(`${this.url}/~/login`, {
|
||||
method: 'post',
|
||||
body: `password=${this.code}`,
|
||||
credentials: 'include',
|
||||
}).then(response => {
|
||||
}).then((response) => {
|
||||
if (this.verbose) {
|
||||
console.log('Received authentication response', response);
|
||||
}
|
||||
@ -160,25 +184,28 @@ export class Urbit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the SSE pipe for the appropriate channel.
|
||||
*/
|
||||
async eventSource(): Promise<void> {
|
||||
if(this.sseClientInitialized) {
|
||||
if (this.sseClientInitialized) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if(this.lastEventId === 0) {
|
||||
if (this.lastEventId === 0) {
|
||||
// Can't receive events until the channel is open,
|
||||
// so poke and open then
|
||||
await this.poke({ app: 'hood', mark: 'helm-hi', json: 'Opening API channel' });
|
||||
await this.poke({
|
||||
app: 'hood',
|
||||
mark: 'helm-hi',
|
||||
json: 'Opening API channel',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.sseClientInitialized = true;
|
||||
return new Promise((resolve, reject) => {
|
||||
const sseOptions: SSEOptions = {
|
||||
headers: {}
|
||||
headers: {},
|
||||
};
|
||||
if (isBrowser) {
|
||||
sseOptions.withCredentials = true;
|
||||
@ -200,7 +227,7 @@ export class Urbit {
|
||||
} else {
|
||||
const err = new Error('failed to open eventsource');
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
onmessage: (event: EventSourceMessage) => {
|
||||
if (this.verbose) {
|
||||
@ -208,14 +235,17 @@ export class Urbit {
|
||||
}
|
||||
if (!event.id) return;
|
||||
this.lastEventId = parseInt(event.id, 10);
|
||||
if((this.lastEventId - this.lastAcknowledgedEventId) > 20) {
|
||||
if (this.lastEventId - this.lastAcknowledgedEventId > 20) {
|
||||
this.ack(this.lastEventId);
|
||||
}
|
||||
|
||||
if (event.data && JSON.parse(event.data)) {
|
||||
const data: any = JSON.parse(event.data);
|
||||
|
||||
if (data.response === 'poke' && this.outstandingPokes.has(data.id)) {
|
||||
if (
|
||||
data.response === 'poke' &&
|
||||
this.outstandingPokes.has(data.id)
|
||||
) {
|
||||
const funcs = this.outstandingPokes.get(data.id);
|
||||
if (data.hasOwnProperty('ok')) {
|
||||
funcs.onSuccess();
|
||||
@ -226,22 +256,30 @@ export class Urbit {
|
||||
console.error('Invalid poke response', data);
|
||||
}
|
||||
this.outstandingPokes.delete(data.id);
|
||||
} else if (data.response === 'subscribe'
|
||||
&& this.outstandingSubscriptions.has(data.id)) {
|
||||
} else if (
|
||||
data.response === 'subscribe' &&
|
||||
this.outstandingSubscriptions.has(data.id)
|
||||
) {
|
||||
const funcs = this.outstandingSubscriptions.get(data.id);
|
||||
if (data.hasOwnProperty('err')) {
|
||||
console.error(data.err);
|
||||
funcs.err(data.err, data.id);
|
||||
this.outstandingSubscriptions.delete(data.id);
|
||||
}
|
||||
} else if (data.response === 'diff' && this.outstandingSubscriptions.has(data.id)) {
|
||||
} else if (
|
||||
data.response === 'diff' &&
|
||||
this.outstandingSubscriptions.has(data.id)
|
||||
) {
|
||||
const funcs = this.outstandingSubscriptions.get(data.id);
|
||||
try {
|
||||
funcs.event(data.json);
|
||||
} catch (e) {
|
||||
console.error('Failed to call subscription event callback', e);
|
||||
}
|
||||
} else if (data.response === 'quit' && this.outstandingSubscriptions.has(data.id)) {
|
||||
} else if (
|
||||
data.response === 'quit' &&
|
||||
this.outstandingSubscriptions.has(data.id)
|
||||
) {
|
||||
const funcs = this.outstandingSubscriptions.get(data.id);
|
||||
funcs.quit(data);
|
||||
this.outstandingSubscriptions.delete(data.id);
|
||||
@ -253,7 +291,7 @@ export class Urbit {
|
||||
},
|
||||
onerror: (error) => {
|
||||
console.warn(error);
|
||||
if(!(error instanceof FatalError) && this.errorCount++ < 4) {
|
||||
if (this.errorCount++ < 4) {
|
||||
this.onRetry && this.onRetry();
|
||||
return Math.pow(2, this.errorCount - 1) * 750;
|
||||
}
|
||||
@ -265,7 +303,7 @@ export class Urbit {
|
||||
throw new Error('Ship unexpectedly closed the connection');
|
||||
},
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,7 +339,7 @@ export class Urbit {
|
||||
this.lastAcknowledgedEventId = eventId;
|
||||
const message: Message = {
|
||||
action: 'ack',
|
||||
'event-id': eventId
|
||||
'event-id': eventId,
|
||||
};
|
||||
await this.sendJSONtoChannel(message);
|
||||
return eventId;
|
||||
@ -311,12 +349,12 @@ export class Urbit {
|
||||
const response = await fetch(this.channelUrl, {
|
||||
...this.fetchOptions,
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(json)
|
||||
body: JSON.stringify(json),
|
||||
});
|
||||
if(!response.ok) {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to PUT channel');
|
||||
}
|
||||
if(!this.sseClientInitialized) {
|
||||
if (!this.sseClientInitialized) {
|
||||
await this.eventSource();
|
||||
}
|
||||
}
|
||||
@ -335,23 +373,23 @@ export class Urbit {
|
||||
let done = false;
|
||||
let id: number | null = null;
|
||||
const quit = () => {
|
||||
if(!done) {
|
||||
if (!done) {
|
||||
reject('quit');
|
||||
}
|
||||
};
|
||||
const event = (e: T) => {
|
||||
if(!done) {
|
||||
if (!done) {
|
||||
resolve(e);
|
||||
this.unsubscribe(id);
|
||||
}
|
||||
}
|
||||
};
|
||||
const request = { app, path, event, err: reject, quit };
|
||||
|
||||
id = await this.subscribe(request);
|
||||
|
||||
if(timeout) {
|
||||
if (timeout) {
|
||||
setTimeout(() => {
|
||||
if(!done) {
|
||||
if (!done) {
|
||||
done = true;
|
||||
reject('timeout');
|
||||
this.unsubscribe(id);
|
||||
@ -369,18 +407,11 @@ export class Urbit {
|
||||
* @param json The data to send
|
||||
*/
|
||||
async poke<T>(params: PokeInterface<T>): Promise<number> {
|
||||
const {
|
||||
app,
|
||||
mark,
|
||||
json,
|
||||
ship,
|
||||
onSuccess,
|
||||
onError
|
||||
} = {
|
||||
onSuccess: () => { },
|
||||
onError: () => { },
|
||||
const { app, mark, json, ship, onSuccess, onError } = {
|
||||
onSuccess: () => {},
|
||||
onError: () => {},
|
||||
ship: this.ship,
|
||||
...params
|
||||
...params,
|
||||
};
|
||||
const message: Message = {
|
||||
id: this.getEventId(),
|
||||
@ -388,7 +419,7 @@ export class Urbit {
|
||||
ship,
|
||||
app,
|
||||
mark,
|
||||
json
|
||||
json,
|
||||
};
|
||||
const [send, result] = await Promise.all([
|
||||
this.sendJSONtoChannel(message),
|
||||
@ -401,9 +432,9 @@ export class Urbit {
|
||||
onError: (event) => {
|
||||
onError(event);
|
||||
reject(event.err);
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|
||||
}),
|
||||
]);
|
||||
return result;
|
||||
}
|
||||
@ -417,19 +448,12 @@ export class Urbit {
|
||||
* @param handlers Handlers to deal with various events of the subscription
|
||||
*/
|
||||
async subscribe(params: SubscriptionRequestInterface): Promise<number> {
|
||||
const {
|
||||
app,
|
||||
path,
|
||||
ship,
|
||||
err,
|
||||
event,
|
||||
quit
|
||||
} = {
|
||||
err: () => { },
|
||||
event: () => { },
|
||||
quit: () => { },
|
||||
const { app, path, ship, err, event, quit } = {
|
||||
err: () => {},
|
||||
event: () => {},
|
||||
quit: () => {},
|
||||
ship: this.ship,
|
||||
...params
|
||||
...params,
|
||||
};
|
||||
|
||||
const message: Message = {
|
||||
@ -437,15 +461,19 @@ export class Urbit {
|
||||
action: 'subscribe',
|
||||
ship,
|
||||
app,
|
||||
path
|
||||
path,
|
||||
};
|
||||
|
||||
this.outstandingSubscriptions.set(message.id, {
|
||||
app, path, err, event, quit
|
||||
app,
|
||||
path,
|
||||
err,
|
||||
event,
|
||||
quit,
|
||||
});
|
||||
|
||||
await this.sendJSONtoChannel(message);
|
||||
|
||||
|
||||
return message.id;
|
||||
}
|
||||
|
||||
@ -458,7 +486,7 @@ export class Urbit {
|
||||
return this.sendJSONtoChannel({
|
||||
id: this.getEventId(),
|
||||
action: 'unsubscribe',
|
||||
subscription
|
||||
subscription,
|
||||
}).then(() => {
|
||||
this.outstandingSubscriptions.delete(subscription);
|
||||
});
|
||||
@ -469,9 +497,14 @@ export class Urbit {
|
||||
*/
|
||||
delete() {
|
||||
if (isBrowser) {
|
||||
navigator.sendBeacon(this.channelUrl, JSON.stringify([{
|
||||
action: 'delete'
|
||||
}]));
|
||||
navigator.sendBeacon(
|
||||
this.channelUrl,
|
||||
JSON.stringify([
|
||||
{
|
||||
action: 'delete',
|
||||
},
|
||||
])
|
||||
);
|
||||
} else {
|
||||
// TODO
|
||||
// this.sendMessage('delete');
|
||||
@ -480,7 +513,7 @@ export class Urbit {
|
||||
|
||||
/**
|
||||
* Scry into an gall agent at a path
|
||||
*
|
||||
*
|
||||
* @typeParam T - Type of the scry result
|
||||
*
|
||||
* @remarks
|
||||
@ -496,14 +529,17 @@ export class Urbit {
|
||||
*/
|
||||
async scry<T = any>(params: Scry): Promise<T> {
|
||||
const { app, path } = params;
|
||||
const response = await fetch(`${this.url}/~/scry/${app}${path}.json`, this.fetchOptions);
|
||||
const response = await fetch(
|
||||
`${this.url}/~/scry/${app}${path}.json`,
|
||||
this.fetchOptions
|
||||
);
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a thread
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param inputMark The mark of the data being sent
|
||||
* @param outputMark The mark of the data being returned
|
||||
* @param threadName The thread to run
|
||||
@ -511,15 +547,24 @@ export class Urbit {
|
||||
* @returns The return value of the thread
|
||||
*/
|
||||
async thread<R, T = any>(params: Thread<T>): Promise<R> {
|
||||
const { inputMark, outputMark, threadName, body, desk = this.desk } = params;
|
||||
if(!desk) {
|
||||
throw new Error("Must supply desk to run thread from");
|
||||
const {
|
||||
inputMark,
|
||||
outputMark,
|
||||
threadName,
|
||||
body,
|
||||
desk = this.desk,
|
||||
} = params;
|
||||
if (!desk) {
|
||||
throw new Error('Must supply desk to run thread from');
|
||||
}
|
||||
const res = await fetch(`${this.url}/spider/${desk}/${inputMark}/${threadName}/${outputMark}.json`, {
|
||||
...this.fetchOptions,
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
const res = await fetch(
|
||||
`${this.url}/spider/${desk}/${inputMark}/${threadName}/${outputMark}.json`,
|
||||
{
|
||||
...this.fetchOptions,
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
}
|
||||
);
|
||||
|
||||
return res.json();
|
||||
}
|
||||
@ -536,6 +581,4 @@ export class Urbit {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default Urbit;
|
||||
|
@ -1,3 +0,0 @@
|
||||
// import Urbit from '../../dist/browser';
|
||||
|
||||
// window.Urbit = Urbit;
|
@ -1,14 +0,0 @@
|
||||
// import Urbit from '../../dist/index';
|
||||
|
||||
// async function blastOff() {
|
||||
// const airlock = await Urbit.authenticate({
|
||||
// ship: 'zod',
|
||||
// url: 'localhost:8080',
|
||||
// code: 'lidlut-tabwed-pillex-ridrup',
|
||||
// verbose: true
|
||||
// });
|
||||
|
||||
// airlock.subscribe('chat-view', '/primary');
|
||||
// }
|
||||
|
||||
// blastOff();
|
@ -1,3 +1,3 @@
|
||||
export * from './types';
|
||||
import Urbit from './Urbit';
|
||||
export { Urbit as default };
|
||||
import { Urbit } from './Urbit';
|
||||
export { Urbit as default, Urbit };
|
||||
|
@ -1,46 +1,17 @@
|
||||
import * as http from 'http';
|
||||
|
||||
interface HttpResponse {
|
||||
req: http.ClientRequest;
|
||||
res: http.IncomingMessage;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export function request(
|
||||
url: string,
|
||||
options: http.ClientRequestArgs,
|
||||
body?: string
|
||||
): Promise<HttpResponse> {
|
||||
return new Promise<HttpResponse>((resolve, reject) => {
|
||||
const req = http.request(url, options, res => {
|
||||
let data = "";
|
||||
res.on("data", chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
res.on("end", () => {
|
||||
resolve({ req, res, data });
|
||||
});
|
||||
res.on("error", e => {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
if (body) {
|
||||
req.write(body);
|
||||
}
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
export function camelize(str: string) {
|
||||
return str
|
||||
.replace(/\s(.)/g, function($1: string) { return $1.toUpperCase(); })
|
||||
.replace(/\s(.)/g, function ($1: string) {
|
||||
return $1.toUpperCase();
|
||||
})
|
||||
.replace(/\s/g, '')
|
||||
.replace(/^(.)/, function($1: string) { return $1.toLowerCase(); });
|
||||
.replace(/^(.)/, function ($1: string) {
|
||||
return $1.toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
export function uncamelize(str: string, separator = '-') {
|
||||
// Replace all capital letters by separator followed by lowercase one
|
||||
var str = str.replace(/[A-Z]/g, function (letter: string) {
|
||||
var str = str.replace(/[A-Z]/g, function (letter: string) {
|
||||
return separator + letter.toLowerCase();
|
||||
});
|
||||
return str.replace(new RegExp('^' + separator), '');
|
||||
@ -79,4 +50,4 @@ export function uid(): string {
|
||||
str += _str + '.';
|
||||
}
|
||||
return str.slice(0, -1);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
|
||||
import Urbit from '../src';
|
||||
import { Readable } from 'streams';
|
||||
import 'jest';
|
||||
|
||||
function fakeSSE(messages = [], timeout = 0) {
|
||||
@ -54,7 +52,7 @@ const fakeFetch = (body) => () =>
|
||||
|
||||
const wait = (ms: number) => new Promise((res) => setTimeout(res, ms));
|
||||
|
||||
process.on('unhandledRejection', () => {
|
||||
process.on('unhandledRejection', (error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
@ -91,7 +89,7 @@ describe('Initialisation', () => {
|
||||
)
|
||||
.mockImplementationOnce(() =>
|
||||
Promise.resolve({ ok: true, body: fakeSSE([], 100) })
|
||||
)
|
||||
);
|
||||
|
||||
airlock.onError = jest.fn();
|
||||
try {
|
||||
@ -163,7 +161,7 @@ describe('subscription', () => {
|
||||
)
|
||||
.mockImplementationOnce(() =>
|
||||
Promise.resolve({ ok: false, body: fakeSSE([ack(1, true)]) })
|
||||
)
|
||||
);
|
||||
|
||||
const params = {
|
||||
app: 'app',
|
||||
|
@ -1,23 +1,24 @@
|
||||
{
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "@types"],
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["node_modules", "dist", "tmp"],
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"outDir": "./tmp",
|
||||
"module": "ESNext",
|
||||
"noImplicitAny": true,
|
||||
"target": "ESNext",
|
||||
"pretty": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"strict": false,
|
||||
"pretty": true,
|
||||
"noImplicitAny": true,
|
||||
"noErrorTruncation": true,
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"*" : ["./node_modules/@types/*", "*"]
|
||||
"*": ["./node_modules/@types/*", "*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user