Open dsriseah opened 4 months ago
I like to use fancy padded output, using a pattern like this:
const DBG = false;
const PR = typeof process !== 'undefined' ? 'EndPoint'.padEnd(13) : 'EndPoint:';
const LOG = (...args) => DBG && console.log(PR, ...args);
LOG('hello');
and
import { PR } from '@ursys/core';
const LOG = PR('HTTP', 'TagBlue');
LOG('hello);
which produces output like:
In browserclients console.log always reports the line where it's used. There might be a .bind(console.log)
that works, or I can use my PROMPT utility which uses this pattern:
const PR = UR.ConsoleStyler('MYMOD','tagRed');
console.log(...PR('hello',1, 2));
ConsoleStyler returns a function that destructures into the css syntax to produce this (in Chrome)
It looks a bit different in Firefox and Safari.
When it's possible for a function to return an error and I don't want to use try/catch
, I define a return object type that can either be an object with error
property or a regular successful return
type TReturn = { error?:string, a?:number, b?:number };
function ReturnSomething( id:number ) : TReturn {
const item = LookupItemById(id);
if (item===undefined) return { error:'invalid item id' };
const { day, month } = item;
return { day, month };
}
// use
const { error, a, b } = ReturnSomething(id);
if (error) {
console.log('uh oh, error', error);
} else {
.. do what you need
}
This pattern I have used here and there, but I'm not sure it's a good idea. If a collection operation returns an array with a single object, then it's removed from the array and returned.
function NormalizeData(data: NP_Data): NP_Data {
if (Array.isArray(data) && data.length == 1) return data[0];
return data;
}
// use
const selected = NormalizeData(GetSelection());
In the above case I don't think it's a good idea...I would probably just want to assume that it's always an array, even if it's empty. That's an easy conditional check rather than using Array.isArray()
There's a place in URSYS where this is used when implementing network messaging. Since there can be multiple message handlers, the dispatcher will return an array of responses. However, it's not typical to expected an array of results.
retData = NormalizeData(retData);
pkt.setData(retData); // returns either a single object or array of objects
This might be handled just at the API level, describing the return type.
Also, this can be reinforced with the naming convention of the function
GetItem()
style methods imply there is a single item. It should throw an error if there is more than one item.GetItems()
style method imply there is always an array of items. It's ok if the array is empty or just has a single item.I like to limit the number of parameters passed to functions from 0 to 2; if I need more, then I use a parameter object because I can define it before the function call and be explicit about it in a more readable way.
type TParam = { a:number, b:number };
function DoSomethingToID( id:number, opt: TParam ) {
const { a, b } = opt || {};
}
// use
const options = {
a: 10, // dimension x
b: 20 // dimension y
}
DoSomethingToId(id, options);
[!TIP] TLDR
- paths never have a trailing slash
- directories are paths that have a trailing slash added
- files are paths that do not end with a trailing slash
- filenames do not have slashes anywhere in them (with some exceptions
I make distinction between a directory, a path, and a file. In practical terms, where do you put the slashes?
Known Rules:
/
and references the file system root/
and is similar to fileRelPath but not in all contextsImplied Rules:
./
and is relative to the path to the current file, limited to config files like tsconfig.json
and module imports.Derived Rules:
.editorconfig
or other top-level config file${rootPath}/${relPath}
Therefore:
PATH
as prefix or suffixTo construct a compound path:
`${absPath}/${relPath}/${relPath}`
or
path.join(absPath, relPath, relPath)
Actual files have a file extension, and never ends with no trailing slash. A directory, by comparison, is a path that does have a trailing slash for clarity
Derived Naming Rules:
DIR
are directory paths and end with a slash.FILE
are file paths that do not end with a slash. It's assumed this is the complete or relative path to a fileFILENAME
refer to the name of the file without its leading path information, and therefore contains no slashes. It's ok in some cases to use a ${relPath}/${fileName}
which won't pollute join operations with extra slashesA "Uniform Resource Identifier (URI)" looks like [scheme]:[a bunch of stuff]
. You use the scheme to determine how to parse the rest of it.
[protocol]://[authority]/[?query][#fragment]
urn:[namespace]:[identifier]
So URNs are used to name a resource, but it's not the only game in town:
550e8400-e29b-41d4-a716-446655440000
10.1000/182
hdl:20.1000/100
978-3-16-148410-0
1234-5678
The closest equivalent to a path is the authority, which consists of the authority marker //
that ends with the final slash. You can think of this as [user@domain]
and this ends at the first /
or end of line. Then comes the rest of the URL information which does look like a relPath up the last /
if there is one.
/
indicates a directory which is a collection of files/resources.The wrinkle is that while URLs are standardized, webservers are configurable to assume how to intepret the URL. A common one is to assume that if a file/resource isn't found by the strict definition of a URL, it will then assume that is a directory and look for an index
to return.
An issue for sharing and debating coding patterns