npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

fidonet-squish

v0.0.39

Published

Fidonet Squish message base parser

Downloads

30

Readme

node-fidonet-squish

Build Status NPM version Coverage Status

The Fidonet Squish module is able to read headers and texts of Fidonet echomail messages from Squish message bases according to FSP-1037 draft 3.

(npm package version)

Using Fidonet Squish

When you require() the installed module, you get a constructor that uses the path to a Squish echo base as its parameter:

var Squish = require('fidonet-squish');
var echobase = Squish(basePath);

Names of echo base files are generated by appending lowercase extensions (.sql, .sqi, .sqd) to the given path.

The constructed object has the following methods:

readSQL(callback)

Asynchronously reads the .sql file (Squish lastread storage) into memory and parses it, populating the variable lastreads

readSQI(callback)

Asynchronously reads the .sqi file (Squish index) into memory and parses that index, populating the object's .indexStructure property with an array of objects with the following properties:

  • CRC — Squish hash.

  • offset — the physical offset of the message's data in the .sqd (header) file.

  • MessageNum0 — a message's rebased (zero-based) internal number. Starts from 0 (zero), i.e. .indexStructure[0].MessageNum0 === 0. The basemsgnum value from the “Squish fixed header” (see below) should be added to generate the actual internal number of a message. Deleted messages leave gaps in that numbering (such as .indexStructure[i].MessageNum0 > i and .indexStructure[i].MessageNum0 > .indexStructure[i-1].MessageNum0 + 1) until the message base is packed by an echoprocessor.

readSQD(callback)

Asynchronously reads the .sqd file (Squish data) into memory, populating the object's .SQD property with a raw Buffer. Then calls callback(error).

The data is cached. Subsequent calls to .readSQD won't repeat the reading operation unless the object's .SQD property is null.

size()

Returns .indexStructure.length property (or undefined when .indexStructure is null).

clearCache(cache)

...

readHeader(number, callback)

...

readAllHeaders(callback)

...

decodeHeader(header, options)

...

decodeKludges(header, options)

...

decodeMessage(header, options, callback)

...

numbersForMSGID(MSGID, options, callback)

Return msgnum for MsgId

bufHash32(buffer)

Return hash of buffer

getAvatarsForHeader(header, schemes, avatarOptions)

...

headersForMSGID(MSGID, options, callback)

Works exactly as .numbersForMSGID, but an array of messages' headers (instead of their numbers) is given to the callback: callback(error, headers).

Each of the headers (found for the given MSGID or MSGIDs) has the same properties as a result of .readHeader. Each header is additionally given another property (MessageIndex) that contains its number as found in .numbersForMSGID. (Do not confuse it with JAM's internal MessageNumber property of the same header object.)

getParentNumber(number, callback)

Using the given message's number, finds out that message's parent in the tree of replies (i.e. the message that the given message replies to), calling .readHeader and .readFixedHeaderInfoStruct in the process. Then callback(error, parentNumber) is called, where parentNumber === null if the parent message cannot be found (for example, if the given message is not a reply).

Possible number values (of the given and the found number) start from (and including) 1 and go to (and including) .size() without gaps. (The internal MessageNumber values are used only internally in this method.)

get1stChildNumber(number, callback)

Using the given message's number, finds out the number of its first child in the tree of replies (i.e. the first of the messages that reply to the given message), calling .readHeader and .readFixedHeaderInfoStruct in the process. Then callback(error, childNumber) is called, where childNumber === null if the given message has no replies.

Possible number values (of the given and the found number) start from (and including) 1 and go to (and including) .size() without gaps. (The internal MessageNumber values are used only internally in this method.)

getNextChildNumber(number, callback)

Using the given message's number, finds out the number of its next sibling in the tree of replies (i.e. the next of the messages that reply to the given message's parent), calling .readHeader and .readFixedHeaderInfoStruct in the process. Then callback(error, siblingNumber) is called, where siblingNumber === null if such sibling message cannot be found (for example, if the given message is not a reply or if it's the last of the replies ever given to its parent message).

Possible number values (of the given and the found number) start from (and including) 1 and go to (and including) .size() without gaps. (The internal MessageNumber values are used only internally in this method.)

getChildrenNumbers(number, callback)

Using the given message's number, finds out the numbers of its children in the tree of replies (i.e. the messages that reply to the given message), calling .get1stChildNumber and (probably) .getNextChildNumber in the process. Then callback(error, childrenNumbers) is called, where childrenNumbers is an array (can be [] if the given message has no replies).

Possible number values (of the given and the found numbers) start from (and including) 1 and go to (and including) .size() without gaps. (The internal MessageNumber values are used only internally in this method.)

getOrigAddr(header, decodeOptions, callback)

...

Locking files

The module does not lock any files and does not create any “lock files” (flag files, semaphore files). The module's caller should control the access to the message base.

That's because Fidonet software uses different locking methods. For example, GoldED+ uses OS file locking (as seen in its source code) and HPT uses a lock file (the file's name is given on the LockFile line in the HPT's config). It would complicate the module if it were the module's job to know what locking is necessary.